HOME>WEBプログラム覚書>[CakePHP 2.X]PaginatorComponent で検索条件とかが反映されない場合。

[CakePHP 2.X]PaginatorComponent で検索条件とかが反映されない場合。

なんかうまく動く時と動かない時があったのでちょっと整理。

CakePHP2系ではController::paginate()はdeprecatedとなっていますが、
いちおう、2.3でも動きます。が、そのせいで書き方をごっちゃにしてしまうとうまく動かなかったりします。

Controller::paginate()

この書き方はたぶん1系から現在の2.3.Xまで動きますが、まぁやめておいた方が良いでしょう。

Controller/PostsController.php

  1. <?php
  2. class PostsController extends AppController {
  3.  
  4.     // ページングパラメーター
  5.     public $paginate = array(
  6.         'Post' => array(
  7.             'conditions' => array('Post.category_id' => 1),
  8.             'limit' => 10,
  9.             'order' => array(
  10.                 'Post.title' => 'asc'
  11.             )
  12.         )
  13.     );
  14.  
  15.     public function index()
  16.     {
  17.         $posts = $this->paginate('Post');
  18.         $this->set(compact('posts'));
  19.     }
  20. }
  21. ?>

PaginatorComponent::paginate()

でもってdeprecatedであるController::paginate()を利用しない場合、
下記のようにコンポーネントの宣言をおこないPaginatorComponent::paginate()を利用します。

Controller/PostsController.php

  1. <?php
  2. class PostsController extends AppController {
  3.  
  4.     // コンポーネント
  5.     public $components = array('Paginator');
  6.  
  7.     // ページングパラメーター
  8.     public $paginate = array(
  9.         'Post' => array(
  10.             'conditions' => array('Post.category_id' => 1),
  11.             'limit' => 10,
  12.             'order' => array(
  13.                 'Post.title' => 'asc'
  14.             )
  15.         )
  16.     );
  17.  
  18.     public function index()
  19.     {
  20.         $posts = $this->Paginator->paginate('Post');
  21.         $this->set(compact('posts'));
  22.     }
  23. }
  24. ?>

が、これはうまく動きません。

Controller::paginate()は、$paginateをPaginatorComponentに渡してくれますが、
PaginatorComponent::paginate()を直接利用する場合、ページングパラメーターは
PaginatorComponent::$settingsに自分でセットしなければなりません。

Controller/PostsController.php

  1. <?php
  2. class PostsController extends AppController {
  3.  
  4.     // コンポーネント
  5.     public $components = array('Paginator');
  6.  
  7.     // ページングパラメーター
  8.     public $paginate = array(
  9.         'Post' => array(
  10.             'conditions' => array('Post.category_id' => 1),
  11.             'limit' => 10,
  12.             'order' => array(
  13.                 'Post.title' => 'asc'
  14.             )
  15.         )
  16.     );
  17.  
  18.     public function index()
  19.     {
  20.         // ページングパラメーターをセット
  21.         $this->Paginator->settings = $this->paginate;
  22.         $posts = $this->Paginator->paginate('Post');
  23.         $this->set(compact('posts'));
  24.     }
  25. }
  26. ?>

この使い方をする場合、Controller::$paginateは別になくてもよくなります。
PaginatorComponent::paginate()の直前に設定することで条件がわかりやすくていいと思います。
(Controller::paginate()の場合でも、Controller::$paginateを設定すればいいわけですが。)

Controller/PostsController.php

  1. <?php
  2.     public function index()
  3.     {
  4.         // ページングパラメーターをセット
  5.         $this->Paginator->settings = array(
  6.             'conditions' => array('Post.tag_id' => 3),
  7.             'limit' => 10
  8.         );
  9.         $posts = $this->Paginator->paginate('Post');
  10.         $this->set(compact('posts'));
  11.     }
  12. ?>

書き方は統一したほうが良い

でもって僕がハマったところはここ。
Paginatorをコンポーネント宣言してしまうとController::paginate()利用時にページングパラメーターが反映されなくなります。
検索条件などが反映されてない時などはこのへんを疑ってみましょう。

ページングパラメーターが反映されない書き方

  1. <?php
  2. class PostsController extends AppController {
  3.  
  4.     // コンポーネント
  5.     public $components = array('Paginator');
  6.  
  7.     // ページングパラメーター
  8.     public $paginate = array(
  9.         'Post' => array(
  10.             'conditions' => array('Post.category_id' => 1),
  11.             'limit' => 10,
  12.             'order' => array(
  13.                 'Post.title' => 'asc'
  14.             )
  15.         )
  16.     );
  17.  
  18.     public function index()
  19.     {
  20.         $posts = $this->paginate('Post');
  21.         $this->set(compact('posts'));
  22.     }
  23. }
  24. ?>

今後を考えるとController::paginate()は使わないようにしたほうが良さそうです。

CakePHP2系では、これまでブラックボックスというかCakePHPがオート処理していた部分を
記述しなければならない場合がありますが、何をしているのかがわかるのでコードはとても わかりやすいものになる気がします。

投稿日 2013年9月 4日 04:20
カテゴリ PHP
タグ CakePHP
トラックバック URL http://www.kantenna.com/cgi-bin/mt504/mt-tb.cgi/1331

コメント

ありがとうございます!
cakephp2.3で、ページネータでcontainableビヘイビアを使おうと思って試行錯誤するも、2-3時間はまりっぱなしでした。

こちらの記事を読んで、あっさり解決しました。

(Paginatorコンポーネントのpaginateをコールしていたが、設定はController->paginateに設定していた。。。)

コメントする
Name
Email Address
URL