09 Aug 2009 2 Comments
Pagination & Containable
Some people seem to have issues with using the Containable (CakePHP 1.2 – built-in) behavior and pagination. A very simple way of getting around this is just to set the last argument to false when setting the model relations via the $this->{ModelName}->contain(); method.
This example will not work:
$this->Post->recursive = -1; //include approved comments $this->Post->contain( array( 'Comment' => array( 'conditions' => array( 'Comment.approved' => true ) ) ) ); $this->paginate();
The reason the above code will not work is not because the recursive level is set to -1, but because the paginate() function makes 2 calls (count records + retrieve records) and after the first call the model relations get reset. Simply adding a false to the end of the contain() function call, will cause the model relationships to not be reset and hence data will be returned as per your request.
e.g.
$this->Post->recursive = -1; //include approved comments $this->Post->contain( array( 'Comment' => array( 'conditions' => array( 'Comment.approved' => true ) ) ), false ); $this->paginate();
Don’t forget to reset the model bings after the call if you want to retrieve more information.
$this->Post->resetBindings();
It’s as simple as that.
Feb 08, 2010 @ 16:59:15
I thought that when you used containable that it automatically, un-binds and binds?
Feb 08, 2010 @ 17:07:56
Yes, normally that is the case, but this is the exception. As you can see in the second example a second parameter is sent to the contain method which overrides the automatic binding reset functionality, which then allows us to use the Containable behaviour and pagination.
The default functionality of the Containable behaviour automatically resets the model bindings after processing a query. With pagination, two queries are made, 1 to get the count and another 1 to get the data, hence we disable the automatic bindings reset.
I hope that answers your query.