<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>cakebaker &#187; pagination</title>
	<atom:link href="http://cakebaker.42dh.com/tags/pagination/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Mon, 19 Jul 2010 14:23:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Thinking about the pagination feature</title>
		<link>http://cakebaker.42dh.com/2008/06/29/thinking-about-the-pagination-feature/</link>
		<comments>http://cakebaker.42dh.com/2008/06/29/thinking-about-the-pagination-feature/#comments</comments>
		<pubDate>Sun, 29 Jun 2008 13:47:55 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[pagination]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=618</guid>
		<description><![CDATA[Recently, I was asked by yunhaihuang some questions about advanced pagination stuff I couldn&#8217;t answer satisfactorily&#8230; And that&#8217;s when I realized that the current implementation of the pagination feature of CakePHP contains at least one conceptual flaw (in most pagination scenarios you probably won&#8217;t notice this flaw). Let&#8217;s have a look at pagination at the [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I was asked by yunhaihuang some <a href="http://cakebaker.42dh.com/2006/05/20/four-new-tutorials-about-iis-acl-an-online-editor-and-pagination/#comments">questions</a> about advanced pagination stuff I couldn&#8217;t answer satisfactorily&#8230;</p>
<p>And that&#8217;s when I realized that the current implementation of the pagination feature of CakePHP contains at least one conceptual flaw (in most pagination scenarios you probably won&#8217;t notice this flaw). </p>
<p>Let&#8217;s have a look at pagination at the model level. A paginator is in principle a user of the &#8220;find&#8221; functionality of a model. And as there are many different ways to use this &#8220;find&#8221; functionality, there can also be many paginators. So we have the following relationship: a model is accessed by many paginators. </p>
<p>In the code you don&#8217;t find an explicit paginator object, you define the &#8220;paginators&#8221; with the $paginate array of the controller. With one exception: if you want to use a custom query for the pagination you have to add and implement the methods paginate() and paginateCount() in your model (see the <a href="http://book.cakephp.org/view/249/custom-query-pagination">manual</a> for more details). But there is a snag to it: as soon as you define those methods it is no longer possible to use the default pagination query without workarounds, because now the new methods are always used&#8230; So we can say that the implemented concept is: a model has one pagination query which can be accessed by many paginators.</p>
<p>Another thing I wondered at was the pagination helper. Shouldn&#8217;t there be different instances of this helper if you want to paginate different data sets on the same page? Currently, there is only one instance, and every method allows you to specify the model name to switch the data set (it assumes there is only one data set per model). But I&#8217;m not sure whether the pagination helper is even thought for this use case, at least I couldn&#8217;t figure out how to paginate two data sets (without Ajax)&#8230;</p>
<p>Hopefully these thoughts help to improve the pagination feature in future versions.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/06/29/thinking-about-the-pagination-feature/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Pagination of data from a HABTM relationship</title>
		<link>http://cakebaker.42dh.com/2007/10/17/pagination-of-data-from-a-habtm-relationship/</link>
		<comments>http://cakebaker.42dh.com/2007/10/17/pagination-of-data-from-a-habtm-relationship/#comments</comments>
		<pubDate>Wed, 17 Oct 2007 14:37:06 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[pagination]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2007/10/17/pagination-of-data-from-a-habtm-relationship/</guid>
		<description><![CDATA[Recently I got asked how you could paginate data from a HABTM (hasAndBelongsToMany) relationship. As the answer could be interesting for others, too, I will show a potential solution here. Let&#8217;s say you have the two models Category and Product, and you want to paginate the Products of a certain Category. Your table definition looks [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I got asked how you could paginate data from a HABTM (hasAndBelongsToMany) relationship. As the answer could be interesting for others, too, I will show a potential solution here.</p>
<p>Let&#8217;s say you have the two models Category and Product, and you want to paginate the Products of a certain Category. Your table definition looks like:</p>
<pre>
<code>create table categories (
    id int(11) not null auto_increment,
    name varchar(255) not null,
    primary key (id)
);

create table products (
    id int(11) not null auto_increment,
    name varchar(255) not null,
    primary key (id)
);

create table categories_products (
    category_id int(11) not null,
    product_id int(11) not null
);</code>
</pre>
<p>And the models are:</p>
<pre>
<code>// app/models/category.php
class Category extends AppModel {
    public $hasAndBelongsToMany = array('Product');
}</code>
</pre>
<p>respectively</p>
<pre>
<code>// app/models/product.php
class Product extends AppModel {
    public $hasManyAndBelongsToMany = array('Category');
}</code>
</pre>
<p>Before we move on, let&#8217;s add some test data to the tables:</p>
<pre>
<code>insert into categories (id, name) values (1, 'PHP');
insert into categories (id, name) values (2, 'Framework');

insert into products (id, name) values (1, 'CakePHP');
insert into products (id, name) values (2, 'Zend');
insert into products (id, name) values (3, 'Symfony');
insert into products (id, name) values (4, 'Rails');
insert into products (id, name) values (5, 'Django');

insert into categories_products (category_id, product_id) values (1, 1);
insert into categories_products (category_id, product_id) values (1, 2);
insert into categories_products (category_id, product_id) values (1, 3);

insert into categories_products (category_id, product_id) values (2, 1);
insert into categories_products (category_id, product_id) values (2, 2);
insert into categories_products (category_id, product_id) values (2, 3);
insert into categories_products (category_id, product_id) values (2, 4);
insert into categories_products (category_id, product_id) values (2, 5);</code>
</pre>
<p>Now we want to paginate all products in the category &#8220;PHP&#8221;. For this purpose we write the following code:</p>
<pre>
<code>// app/controllers/categories_controller.php
class CategoriesController extends AppController {
    public $paginate = array('limit' =&gt; 2);
		
    public function index() {	
        $data = $this-&gt;paginate('Category', array('Category.id' =&gt; 1));
        debug($data);
        exit;		
    }
}</code>
</pre>
<p>The output of this code is:</p>
<pre>
<code>Array
(
    [0] =&gt; Array
        (
            [Category] =&gt; Array
                (
                    [id] =&gt; 1
                    [name] =&gt; PHP
                )
            [Product] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [id] =&gt; 1
                            [name] =&gt; CakePHP
                        )
                    [1] =&gt; Array
                        (
                            [id] =&gt; 2
                            [name] =&gt; Zend
                        )
                    [2] =&gt; Array
                        (
                            [id] =&gt; 3
                            [name] =&gt; Symfony
                        )
                )
        )
)</code>
</pre>
<p>Obviously the wrong approach as we get three products instead of two. Hm, maybe we have to use the Product model in the paginate statement. Let&#8217;s try it:</p>
<pre>
<code>// app/controllers/categories_controller.php
class CategoriesController extends AppController {
    public $paginate = array('limit' =&gt; 2);
		
    public function index() {	
        $data = $this-&gt;paginate('Product', array('Category.id' =&gt; 1));
        debug($data);
        exit;		
    }
}</code>
</pre>
<p>This causes the following error:</p>
<pre>
<code>SQL Error: 1054: Unknown column 'Category.id' in 'where clause'</code>
</pre>
<p>Hm. Couldn&#8217;t we use somehow the mapping table required for our HABTM association? Sure, we can create a model for it:</p>
<pre>
<code>// app/model/categories_product.php
class CategoriesProduct extends AppModel {
    public $belongsTo = array('Category', 'Product');
}</code>
</pre>
<p>And use this model in the paginate statement:</p>
<pre>
<code>// app/controllers/categories_controller.php
class CategoriesController extends AppController {
    public $paginate = array('limit' =&gt; 2);
		
    public function index() {	
        $data = $this-&gt;paginate('CategoriesProduct', array('Category.id' =&gt; 1));
        debug($data);
        exit;		
    }
}</code>
</pre>
<p>This time we get the expected result (at least up to RC4 of CakePHP 1.2):</p>
<pre>
<code>Array
(
    [0] =&gt; Array
        (
            [CategoriesProduct] =&gt; Array
                (
                    [category_id] =&gt; 1
                    [product_id] =&gt; 1
                )
            [Category] =&gt; Array
                (
                    [id] =&gt; 1
                    [name] =&gt; PHP
                )
            [Product] =&gt; Array
                (
                    [id] =&gt; 1
                    [name] =&gt; CakePHP
                )
        )
    [1] =&gt; Array
        (
            [CategoriesProduct] =&gt; Array
                (
                    [category_id] =&gt; 1
                    [product_id] =&gt; 2
                )
            [Category] =&gt; Array
                (
                    [id] =&gt; 1
                    [name] =&gt; PHP
                )
            [Product] =&gt; Array
                (
                    [id] =&gt; 2
                    [name] =&gt; Zend
                )
        )
)</code>
</pre>
<p>However, in CakePHP 1.2.1.8004 the previous solution no longer works. The CategoriesProduct model is no longer needed. And by following the <a href="http://bakery.cakephp.org/articles/view/quick-tip-doing-ad-hoc-joins-in-model-find">tutorial</a> about ad-hoc joins we have to change the CategoriesController to:</p>
<pre>
<code>// app/controllers/categories_controller.php
class CategoriesController extends AppController {
    public $paginate = array('Product' =&gt; array('limit' =&gt; 2, 'joins' =&gt; array( 
        array( 
            'table' =&gt; 'categories_products', 
            'alias' =&gt; 'CategoriesProduct', 
            'type' =&gt; 'inner',  
            'conditions'=&gt; array('CategoriesProduct.product_id = Product.id') 
        ), 
        array( 
            'table' =&gt; 'categories', 
            'alias' =&gt; 'Category', 
            'type' =&gt; 'inner',  
            'conditions'=&gt; array( 
                'Category.id = CategoriesProduct.category_id', 
                'Category.id' =&gt; 1 
            ) 
        ))));

    public function index() {
        $data = $this-&gt;paginate('Product');
        debug($data);
        exit;
    }	
}</code>
</pre>
<p>With those changes the debug output should now look like:</p>
<pre>
<code>Array
(
    [0] =&gt; Array
        (
            [Product] =&gt; Array
                (
                    [id] =&gt; 1
                    [name] =&gt; CakePHP
                )
            [Category] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [id] =&gt; 1
                            [name] =&gt; PHP
                        )
                    [1] =&gt; Array
                        (
                            [id] =&gt; 2
                            [name] =&gt; Framework
                        )
                )
        )
    [1] =&gt; Array
        (
            [Product] =&gt; Array
                (
                    [id] =&gt; 2
                    [name] =&gt; Zend
                )
            [Category] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [id] =&gt; 1
                            [name] =&gt; PHP
                        )
                    [1] =&gt; Array
                        (
                            [id] =&gt; 2
                            [name] =&gt; Framework
                        )
                )
        )
)</code>
</pre>
<p>If there is a better solution, please let me know ;-)</p>
<p>Update 2009-02-01: Adding solution for CakePHP 1.2.1.8004.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2007/10/17/pagination-of-data-from-a-habtm-relationship/feed/</wfw:commentRss>
		<slash:comments>92</slash:comments>
		</item>
	</channel>
</rss>
