5丁目通信(仮称)

とある5丁目で活動する還暦を過ぎたWebプログラマーの覚え書きです。それとかかってくる迷惑電話や、家業のアパート経営について。

CakePHP:paginateのsortに複数のソート項目を追加した話し


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

にしてくれます。

,