CakePHP Paginate Сортировка по содержанию данных

Это простое приложение для отслеживания хобби пользователей. У пользователя может быть много хобби, которые организованы в различные группы хобби.

Итак, у меня есть 4 связанных таблицы: пользователи, users_hobbies, хобби, hobby_groups.

users — это отношение «есть и принадлежит многим» к хобби через таблицу соединений users_hobbies.
хобби принадлежит-хобби-группе, хобби-группа имеет много хобби

Имеет смысл, пока довольно просто.

В UsersHobbiesController у меня есть:

$paginate = [
'contain' => [
'Hobby' => [
'fields' => ['id', 'name'],
'HobbyGroup' => [
'fields' => ['id', 'name']
]
]
]
];

Кроме того, в моей функции index () я создаю нумерацию страниц.

$usersHobbies = $this->paginate('UsersHobby');
$this->set(compact('usersHobbies));

Когда я получаю доступ к переменной $ usersHobbies в моем файле index.ctp View, в нем есть данные, которые я хочу создать для выходной таблицы. Это выглядит как:

array(
(int) 0 => array(
'UsersHobby' => array(...),
'Hobby' => array(
'id' => 'abc-def-ghi',
'name' => 'Jet Skiing',
'HobbyGroup' => array(
'id' => 'oiuy-trew-qldf',
'name' => 'Watersports'
)
)
)
....
)

Чтобы отсортировать таблицу вывода, я добавил несколько столбцов сортировки:

<th><?php echo $this->Paginator->sort('Hobby.name', 'Hobby'); ?></th>
<th><?php echo $this->Paginator->sort('Hobby.HobbyGroup.id', 'Hobby'); ?></th>

Первый заголовок работает для сортировки по имени Хобби. Но я не может получить второй заголовок для сортировки по HobbyGroup. Есть ли простой способ сделать это?

Я искал несколько часов на StackOverflow, но не могу найти ответ, который мне подходит. Благодарю.

2

Решение

Это не будет работать так, как вы ожидаете, из-за того, как CakePHP извлекает данные.

В зависимости от того, как вы настроите свои отношения, случится так, что Cake будет первый выберите хобби и затем сделать еще один запрос для хобби групп.

Поэтому любая сортировка, которую вы применяете ко второму запросу, будет в целом бесполезной и будет потеряна, когда эти данные будут сопоставлены со списком хобби.

Так что у тебя есть

SELECT hobbies....

Затем будет выдан еще один выбор

SELECT hooby_groups WHERE hobby_id IN [list of ids ] ORDER BY hobby_groups_id

Данные из второго выбора будут сопоставлены с первым, так что ваш заказ не так много!

В зависимости от того, какую версию CakePHP вы используете, вы можете сделать несколько вещей:

  1. Определите отношения для использования INNER JOIN Стратегия так позволит избежать создания двух SELECT заявления. Таким образом, order by причина отсортирует все данные, как вы ожидаете. Предостережение заключается в том, что с INNER JOIN Хобби, с которыми не связана ни одна группа, никогда не будет выбрано вашим разбиением на страницы.

  2. Если вы используете CakePHP 2.x, вы можете посмотреть на Пользовательский запрос нумерации страниц и создайте запрос так, как вам нужно, чтобы он работал.

  3. Если вы используете CakePHP 3.x, у вас есть конструктор запросов, и Paginator может разбивать на страницы любой запрос, поэтому вы можете выполнять там свои внутренние объединения.

Чтобы помочь вам, вы можете использовать DebugKit из CakePHP, чтобы увидеть, какие фактические запросы выполняются и как настройка этого параметра влияет на то, как генерируется запрос. Вы увидите, где order by применяется и почему это может не работать.

В CakePHP 2.x вы можете использовать type контролировать, как осуществляется соединение. Вам нужно использовать INNER

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]