Ссылка сортировки по страницам на виртуальное поле / свойство сущности в CakePHP 3.0
Я хочу создать ссылку сортировки по страницам на виртуальное поле/свойство сущности в CakePHP 3.0.
В CakePHP 2.x я использовал для создания виртуального поля , а затем создал ссылку сортировки по страницам на этом поле. Однако в CakePHP 3.0, виртуальные поля были заменены на свойства виртуальных сущностей.
Есть ли способ заставить это работать в CakePHP 3.0?
В моей ситуации у меня есть столбец first_name и last_name, который объединяются как full_name в свойствевиртуальной сущности . Я хочу отсортировать по full_name.
2 ответа:
Как указано в связанных документах, виртуальные свойства не могут использоваться в находках. То есть по замыслу, виртуальные свойства живут только в сущностях, они строятся в PHP после того, как данные были извлечены из базы данных.
Поэтому давайте на время забудем о виртуальных свойствах и сосредоточимся на запросах и вычисляемых столбцах.Вычисляемые столбцы должны быть заданы через
sortWhitelist
Так же, как и столбцы связанных моделей, вычисляемые столбцы должны быть указаны в
sortWhitelist
вариант для того, чтобы быть пригодным для сортировки!Через параметры пагинации
Здесь у вас есть некоторые опции, например, вы можете определить вычисляемые столбцы в параметрах разбиения на страницы:
$this->paginate = [ // ... 'sortWhitelist' => [ 'id', 'first_name', 'last_name', 'full_name', // ... ], 'fields' => [ 'id', 'first_name', 'last_name', 'full_name' => $this->Table->query()->func()->concat([ 'first_name' => 'literal', 'last_name' => 'literal' ]), // ... ], 'order' => [ 'full_name' => 'DESC' ] ];
Пользовательский искатель
Другой, более многоразовый вариант-использовать пользовательский finder:
$this->paginate = [ // ... 'sortWhitelist' => [ 'id', 'first_name', 'last_name', 'full_name', // ... ], 'finder' => 'withFullName', 'order' => [ 'full_name' => 'DESC' ] ];
public function findWithFullName(\Cake\ORM\Query $query, array $options) { return $query->select([ 'id', 'first_name', 'last_name', 'full_name' => $query->func()->concat([ 'first_name' => 'literal', 'last_name' => 'literal' ]), // ... ]); }
- Поваренная книга > Контроллеры > компоненты > разбиение на страницы > использование контроллера:: разбиение на страницы()
- Поваренная книга > ... ORM > извлечение наборов данных и результатов > пользовательские методы поиска
Отдельный пользовательский запрос
Также можно напрямую передавать объекты запроса в
Controller::paginate()
:$this->paginate = [ // ... 'sortWhitelist' => [ 'id', 'first_name', 'last_name', 'full_name', // ... ], 'order' => [ 'full_name' => 'DESC' ] ]; $query = $this->Table ->find() ->select(function (\Cake\ORM\Query $query) { return [ 'id', 'first_name', 'last_name', 'full_name' => $query->func()->concat([ 'first_name' => 'literal', 'last_name' => 'literal' ]), // ... ]; }); $results = $this->paginate($query);
Установите порядок сортировки по умолчанию таким же, как и в виртуальном поле:
public $paginate = [ 'order' => [ 'first_name' => 'ASC', 'last_name' => 'ASC', ] ];
Затем просто добавьте следующее в ваше представление, чтобы предотвратить переопределение пагинатором порядка по умолчанию, если он не указан пользователем:
if (empty($_GET['direction'])) { $this->Paginator->options(['url' => ['direction' => null, 'sort' => null]]); }