CakePHPで用意されているpaginateのsortのメモです。paginateのsortは便利ですが、最初はテーブルの1項目しかソートの対象になりません。お客さんから、「価格」と並び替えるときに、もう一つ「価格条件」でも合わせてソートしてくれという入り用とのこと。しかし、CakePHPのレファレンスによると、ソートするには一つの項目だけしかソート項目を指定できません。・・・/cake/libs/controller/controller.phpのpaginate()のソースを追っても、複数のソート項目を設定できるようにはなっていません。
そこで、再度調べてみると、検索する前にモデルでbeforeFind()を呼んくれるとのこと。そこでモデルでbeforeFind()を定義して、ここでソート項目を追加してしまうことにしました。例えばこんな感じ(だいぶコードを省略しています)。
function beforeFind($queryData) {
array_unshift($queryData['order'], array('XXX.item' => ‘desc’));
return($queryData);
}
ORDER BY句の最初に
XXX.item desc
が追加されます。$queryData[‘order’]は配列で、配列の順番でORDER BY句に追加していきますので、
$queryData['order'][] = array('XXX.item' => ‘desc’);
とすると、ORDER BY句の最後に、
, XXX.item desc
が追加されます。これで、複数の項目でSORTできます。
ここからついでの話しです。ORDER BY句に、ちょっとしたSQL関数を追加したい場合、例えば、
XXX.item is NULL desc
を追加した場合(あまりありませんが・・・)、
array('XXX.item is NULL' => ‘desc’)
と指定してしまうと、
“XXX”.”item” is NULL” dess
と解析されてSQLエラーになってしまいます。これは、
array('(XXX.item) is NULL' => ‘desc’)
として括弧で括ってあげれば、ORDER BY句には、期待通り、
(XXX.item) is NULL desc
にしてくれます。