【CakePHP】Paginator × フィルター機能でのバグ解消奮闘記


Paginator、めっちゃ便利なんですが、
他の機能と組み合わせようとしたとき、なんとも使い勝手が悪い。。

バージョンの違いなのかなんなのか、バグ解消にかなり奮闘したので記録しておきます。

【前提としてやりたいこと】
・ユーザのリストを表示して、かつページネーションしたい
・ユーザのグルーピング（今回はStudent,Teacher,Staff）でフィルターをかけたい(Postメソッド)

【今回のバグ】
・Paginate機能でページング(2ページ目以降に遷移)したのちにフィルターをかけると、
　ページ番号が維持されたままフィルターがかかってしまう
　　→　フィルター後に、そのページが存在しない場合エラーになる
・フィルター後にページングすると、フィルターが解除されてしまう

【バージョン】
cakephp 2.5.4

Paginatorの基本的な使い方なんかはこのあたりの記事が参考になります
[初めての[CakePHP2.x]での開発、そして挫折するまで日記～その25 ページネーションを使ってみる](http://www.tailtension.com/cakephp/675/)


##ページ番号が維持されてしまう
結論から言うと、ページ番号を1に戻したいタイミングにこれを追加する

```UsersController.php
$this->request->params['named']['page'] = 1;
```

これだけなのに・・全然情報出てこなくて辛かったw

view側で$paginator->optionsを変えることでも設定できるらしいが、
おそらくPaginatorのヘルパーを使った動作のときのみで動くらしく、私のケースはダメだった。。
上でダメだった人は試してみてもいいかも
参考：[検索結果をpaginateする方法](http://d.hatena.ne.jp/seto-san/20090813/1250171541)

##フィルター後にページングすると、フィルターが解除されてしまう

これは有名な落とし穴なようで、検索するとたくさん出てきました
主に対処方法は２種類で、

- Sessionを使う方法
- Getでデータを保持して持ち回る方法

があるようです。
私の場合はSessionを使う方法で解決しました！

参考元にお世話になった記事はこちら
[検索結果をpaginateする方法](http://d.hatena.ne.jp/seto-san/20090813/1250171541)

手順としては、
①保持したいデータをSessionに書き込む

```
$this->Session->write('filter', $filter);
```

②Post以外のときに、Sessionデータがあるか確認して、あれば読み込む

```
if($this->Session->check('filter')) {
	$sort = $this->Session->read('filter');
　　・・・
```

以上！
Viewファイルは特に触れることなくいけます

Get取得の方法でいく場合はこちらを参考にするといいかもです
[CakePHPのページネーションでPostされたデータを持ち回る方法(Paginator helper)](http://www.yaunix.com/2011/01/07/cakephp%E3%81%AE%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A7post%E3%81%95%E3%82%8C%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E6%8C%81%E3%81%A1%E5%9B%9E%E3%82%8B/)


コントローラー全体(今回使用しているindexメソッドのみ)はこんな感じ

```UsersController.php
    public function index() {
        $this->Paginator->settings = $this->paginate;
        $this->User->recursive = 0;

        $this->set('total', $this->User->find('count', array(
                'conditions' => array('del_flg' => '0'))));

        if ($this->request->is('post')) {
            $filter = $this->request->data['Filter']['group_id'];
            $this->Session->write('filter', $filter);
            $this->set('filter', $filter);
            $this->request->params['named']['page'] = 1;
            
            if ($filter == '0') {
                $this->set('users', $this->Paginator->paginate('User', array('del_flg' => '0')));
            } else {
                $this->set('users', $this->Paginator->paginate('User', array('del_flg' => '0', 'group_id' => $filter)));
            }
        } else { //post処理以外(フィルターを使ったとき以外)
            if($this->Session->check('filter')) {
                $filter = $this->Session->read('filter');
                if ($filter == '0') {
                    $this->set('users', $this->Paginator->paginate('User', array('del_flg' => '0')));
                } else { 
                    $this->set('users', $this->Paginator->paginate('User', array('group_id' => $filter,'del_flg' => '0')));
                }
            } else {
                $this->set('users', $this->Paginator->paginate('User', array('del_flg' => '0')));
            }
        }
	}
```

あまりキレイではなく恐縮ですが・・
同じバグではまった方、参考にどぞー！