cakephperの日記(CakePHP, Laravel, PHP) Twitter


継続的WebセキュリティテストサービスVAddyを始めました!

2015-04-27

CakePHP2のPaginateでCASE式などを使ったフィールドを指定してソートする方法

CakePHP2で、CASEやCONCATなどを使ってテーブルに存在しないフィールド名でソートを行う場合、例えば下記のようにすると思います。

<?php
$params = [
  'fields' => ['CASE WHEN User.age >= 20 then 1 else 0 END AS adult'],
  'order'  => ['adult DESC']
];
find('all', $params);

通常のfindであれば問題ないですが、ページングのorderでこのフィールドを指定しても効いてくれません。

このような場合は、モデルのバーチャルフィールドを利用します。

<?php
//コントローラの中でUserモデルを利用
$this->User->virtualFields['adult'] = 'CASE WHEN User.age >= 20 then 1 else 0 END';
$this->Paginator->settings = ['order' => ['User.adult' => 'desc']];

参考:

http://book.cakephp.org/2.0/ja/models/virtual-fields.html

"バーチャルフィールドは find 時に普通のフィールドと同じように振舞うため、Controller::paginate() はバーチャルフィールドでもソートすることができます。"

http://stackoverflow.com/questions/21160171/implement-order-by-case-with-paginator-in-cakephp

トラックバック - http://d.hatena.ne.jp/cakephper/20150427/1430112358