読者です 読者をやめる 読者になる 読者になる
一人もくもく会 α verでサービス開始しました。

CakePHPのページネーションのソートでリレーションモデルを使う

CakePHPは下記のようにして一覧ページを指定カラムでソートできるリンクが作れる。

$this->Paginator->sort('age', '年齢');

この時、一覧ページにリレーションデータの列などがあると
そちらでもソートできないといけないのだが、
$this->paginateにorderを指定しても
それはデフォルトとして扱われてしまいソートを変更できない。

ではどうするかというと、該当モデルに
paginateというメソッドを追加すると
そちらで自由にデータをとる処理を作成できる。
なので下記のようにして特定のフィールドだけ独自処理にし
あとは普通のfind allにしたりなどができる。
下記のように複数フィールドを使うことも。

public function paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra) {
	if (isset($order['User.parent_id'])) {
		$direction = $order['User.parent_id'];
		$order = array(
			'Parent.group_id' => $direction,
			'User.parent_id' => $direction,
		);
	}
	$parameters = array(
		'conditions' => $conditions,
		'fields' => $fields,
		'order' => $order,
		'limit' => $limit,
		'page' => $page,
		'recursive' => $recursive,
	);
	return $this->find('all', $parameters);
}

$orderは文字列で来る場合があり、
php5.3未満だとissetのところがtrueになってしまうようなので
is_arrayも行った方が良いらしい。