Ссылка сортировки страниц на виртуальное поле / свойство сущности в 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 > извлечение данных и наборов результатов > пользовательские методы Finder
отдельный пользовательский запрос
также можно напрямую передавать объекты запроса в 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]]); }