CakePHP 4 でソートリンクが動かないときの確認事項
はじめに
この記事では CakePHP 4 の Paginator ヘルパーのソート機能が動作しない場合にチェックするポイントをご紹介します。
- Paginator - 4.x
- https://book.cakephp.org/4/en/views/helpers/paginator.html
- Pagination - 4.x
- https://book.cakephp.org/4/en/controllers/pagination.html
1. order() を使っていないか
初期ソートの指定に order() を使うとソートリンクが動作しません。
src/Controller/UsersController.php
// 【注意】動作しません
$query = $this->Users->find()
->order(['full_name']);
$users = $this->paginate($query);
下記のように $paginate 変数で指定すれば OK です。
src/Controller/UsersController.php
$this->paginate = [
'order' => ['full_name'],
];
$query = $this->Users->find();
$users = $this->paginate($query);
2. sortableFields の設定
リレーション先の項目でソートしたい場合には、コントローラの $paginate 変数で sortableFields を指定する必要があります。
src/Controller/UsersController.php
$this->paginate = [
'sortableFields' => [
'Users.full_name',
'Roles.name',
]
];
$query = $this->Users->find()
->contain(['Roles']);
$users = $this->paginate($query);
templates/Users/index.php
<th><?= $this->Paginator->sort('Users.full_name', '氏名') ?></th>
<th><?= $this->Paginator->sort('Roles.name', '役割') ?></th>
項目名の重複がない場合はテーブルのエイリアス名は未指定でも動作します。
src/Controller/UsersController.php
$this->paginate = [
'sortableFields' => [
'full_name',
'name',
]
];
templates/Users/index.php
<th><?= $this->Paginator->sort('full_name', '氏名') ?></th>
<th><?= $this->Paginator->sort('name', '役割') ?></th>
3. エイリアス名の有無を統一
テーブルのエイリアス名の有無は、コントローラ $paginate 変数の order と sortableFields 、テンプレの sort() で統一する必要があります。
例えば下記の場合は、コントローラの sortableFields にはエイリアス名があって、テンプレの sort() の引数には無いので、ソートリンクが機能しません。
src/Controller/UsersController.php
// 【注意】動作しません
// エイリアス名が sotrableFields にはあって、テンプレにはない
$this->paginate = [
'sortableFields' => [
'Users.full_name',
'Roles.name',
]
];
templates/Users/index.php
<th><?= $this->Paginator->sort('full_name', '氏名') ?></th>
<th><?= $this->Paginator->sort('name', '役割') ?></th>
また下記の場合は、コントローラの order() で full_name のエイリアス名が無いため、氏名のソートリンクだけが機能しません。
src/Controller/UsersController.php
// 【注意】full_name でソートするときに動作しません
$this->paginate = [
'order' => [
// ここだけエイリアス名がない
'full_name',
],
'sortableFields' => [
'Users.full_name',
'Roles.name',
]
];
templates/Users/index.php
<th><?= $this->Paginator->sort('Users.full_name', '氏名') ?></th>
<th><?= $this->Paginator->sort('Roles.name', '役割') ?></th>