【CakePHP 2.x】Paginatorコンポ―ネントのorderやlimitの設定が効かずに困った話
CakePHP Cookbook 2.x ドキュメントを見て書いてみたのですが、orderやlimitの設定をしても、デフォルトの設定で動いてしまい、だいぶハマりました^^;
環境
- PHP 5.3.29
- CakePHP 2.6.3
最初に書いたコード
<?php class HogesController extends AppController { //Paginatorコンポーネントを読み込み public $components = array('Paginator'); //$pagenateに検索条件を設定 public $pagenate = array( 'limit' => 10, 'maxLimit' => 10, 'order' => array('Hoge.modified' => 'desc') ); public function index() { //paginateメソッドでデータ検索 $this->set('hoges', $this->Paginator->paginate('Hoge')); } }
結果(失敗)
想定では、クエリにLIMIT 10
とORDER BY
が入るはずが
SELECT `Hoge`.`id`, `Hoge`.`modified` FROM `hoge`.`hoges` AS `Hoge` WHERE 1 = 1 LIMIT 20
全く設定が効いてない。。。orz
PaginatorComponentのソースを追って見た
ネットで調べても解決策が見つからず埒が明かないので、PaginatorComponentのソースを追って見ることに。
そしてわかったのは、
- Controllerに定義した$pagenateにはアクセスしていない。
- 設定をコンポーネントに反映させるには、以下の3つのタイミングがある。
- コンポーネントのコンストラクタの引数に渡す。
- コンポーネントのインスタンスの内部変数を書き換える。
- リクエスト時にパラメータとして渡す。(今回は説明を省きます)
1. コンポーネントのコンストラクタの引数に渡す。
コンストラクタの引数に渡すには、コンポーネント読み込みのコードを以下のようにします。
<?php class HogesController extends AppController { //Paginatorコンポーネントを読み込み(ここに引数を入れる) public $components = array( 'Paginator' => array( 'limit' => 10, 'maxLimit' => 10, 'order' => array('Hoge.modified' => 'desc') ) ); public function index() { //paginateメソッドでデータ検索 $this->set('hoges', $this->Paginator->paginate('Hoge')); } }
結果
SELECT `Hoge`.`id`, `Hoge`.`modified` FROM `hoge`.`hoges` AS `Hoge` WHERE 1 = 1 ORDER BY `Hoge`.'modified' desc LIMIT 10
バッチリ!
2. コンポーネントのインスタンスの内部変数を書き換える。
コンポーネント内部では$settingというpublic変数に設定値が格納されています。
それを書き換えてあげればOKです。
<?php class HogesController extends AppController { //Paginatorコンポーネントを読み込み public $components = array('Paginator'); public function index() { //内部変数を書き換え public $this->Paginator->settings = array( 'limit' => 10, 'maxLimit' => 10, 'order' => array('Hoge.modified' => 'desc') ); //paginateメソッドでデータ検索 $this->set('hoges', $this->Paginator->paginate('Hoge')); } }
結果
SELECT `Hoge`.`id`, `Hoge`.`modified` FROM `hoge`.`hoges` AS `Hoge` WHERE 1 = 1 ORDER BY `Hoge`.'modified' desc LIMIT 10
問題なし!
好みと状況に応じて使い分けてください!