Fork me on GitHub
Heads up!
These docs are for Crud v3 - that only works with CakePHP 2.x. For CRUD v4 docs please go to the new documentation site
The CRUD v4 documentation has been completely rewritten, and since CRUD v3 and CRUD v4 API is ~95% identical, it may be worth a look for CRUD v3 users as well until v4 docs are backported for v3.
...toc....

Filling Related Models select boxes

This listener is loaded by default in Crud

If you are used to bake or CakePHP scaffolding you might want to have some control over the data it is sent to the view for filling select boxes for associated models.

Crud component can be configured to return the list of record for all related models or just those you want to in a per-action basis

By default all related model lists for main Crud component model instance will be fetched, but only for add, edit and corresponding admin actions.

For instance if your Post model in associated to Tag and Author, then for the aforementioned actions you will have in your view the $authors and $tags variable containing the result of calling find(‘list’) on each model.

Should you need more fine grain control over the lists fetched, you can configure statically or use dynamic methods:

Configuring relatedModels

You can enable and disable which model relations you want to have automatically fetched very easily, as shown below.

If you set relatedModels to true all model relations will be fetched automatically.

If you set relatedModels to an array, only the related models in that array will be fetched automatically.

If you set relatedModels to false no model relations will be fetched automatically.

<?php
class DemoController extends AppController {

  public $components = [
    'Crud.Crud' => [
      'actions' => [
        'add' => ['relatedModels' => ['Author']],
        'edit' => ['relatedModels' => ['Tag', 'Cms.Page']]
      ]
    ]
  ];

}
?>

It’s possible to dynamically reconfigure the relatedModels listener

<?php
// This can be changed in beforeFilter and the controller action
public function beforeFilter() {
  // Automatically executes find('list') on the User ($users) and Tag ($tags) models
  $this->Crud->action('your_action')->relatedModels(array('User', 'Tag'));

  // Automatically executes find('list') on the User ($users) model
  $this->Crud->action('your_action')->relatedModels(array('User'));

  // Fetch related data from all model relations (default)
  $this->Crud->action('your_action')->relatedModels(true);

  // Don't fetch any related data
  $this->Crud->action('your_action')->relatedModels(false);

  // Get the current configuration
  $config = $this->Crud->action('your_action')->relatedModels();
}
?>

If for any reason you need to alter the query or final results generated by fetching related models lists, you can use Crud.beforeRelatedModel and Crud.afterRelatedModel events to inject your own logic.

Crud.beforeRelatedModel will receive the following parameters in the event subject, which can be altered on the fly before any result is fetched

  • query: An array with options for find(‘list’)
  • viewVar: The name of the variable when set to the view
  • modelName: The name of the associated model
  • associationType: The type of association (belongsTo, hasAndBelongsToMany etc.)
  • associatedModel: The model instance used to fetch the related data (instance of modelName)

Crud.afterRelatedModel will receive the following parameters in the event subject, which can be altered on the fly after results were fetched

  • items: result from calling find(‘list’)
  • viewVar: Variable name to be set on the view with items
  • modelName: The name of the associated model
  • associationType: The type of association (belongsTo, hasAndBelongsToMany etc.)
  • associatedModel: The model instance used to fetch the related data (instance of modelName)

Example

<?php
class DemoController extends AppController {
  //...

  public function beforeFilter() {
    parent::beforeFilter();

    //Authors list should only have the 3 most recen items
    $this->Crud->on('beforeRelatedModel', function($event) {
      if ($event->subject->model instanceof Author) {
        $event->subject->query['limit'] = 3;
        $event->subject->query['order'] = array('Author.created' => 'DESC');
      }
    });

    $this->Crud->on('afterRelatedModel', function($event) {
      if ($event->subject->model instanceof Tag) {
        $event->subject->items += array(0 => 'N/A');
        $event->subject->viewVar = 'labels';
      }
    });

  }

}
?>



comments powered by Disqus