Showing posts with label ajax. Show all posts
Showing posts with label ajax. Show all posts

Saturday, July 12, 2008

Merging ContainableBehavior and PaginatorHelper

This is an update to another article, Taming Containables in CakePHP 1.2. You might want to read it first.


Paginator and Containable are both great, but the documentation is wholly inadequate in discussing how to combine their functionality. After scouring the Cake libraries and existing documentation, however, I have found The Way:

var $paginate = array(
    'limit' => 10,
    'order' => array(
      'Segment.name' => 'asc',
      'Unit.label' => 'asc'
    ),
    'recursive' => 2,
    'conditions' => null,
    'contain' => array(
          'Rental' => array(
            'conditions' => array('Rental.active' => 1),
            'fields' => array('Rental.active', 'Rental.expires'),
            'Contact' => array (
              'fields' => array('Contact.id', 'Contact.forename', 'Contact.surname')
            )
          ),
          'Control',
          'Segment'
        )
  );


This code now appears in my UnitsController. You'll note a few differences from the previous version, however.

I have consolidated Rental using standard Model::find('all') syntax and I can now select my fields and conditions without worrying about order precedence.

More interesting still, ContainableBehavior seems to implicitly extend to all sub-arrays, allowing me to provide still more conditions and fields to those aspects.

The inherent possibilities for creating complex multi-model AJAX filters are very promising.

You may also be wondering why I set $paginate['conditions'] to null. I want to be able to programmatically add dynamic filters to the Units model, so this provides an easy way in. It also seems to make PHP happier at runtime if I don't attempt to add that array element. Since the conditions aren't applied until the Model::paginate function is actually called, there is no significant performance or capability hit.

Hint: This also means that we can very heavily alter our paginate variable within functions, for those not uncommon cases where you'll be paginating very different lists within the same controller.