Это простое приложение для отслеживания хобби пользователей. У пользователя может быть много хобби, которые организованы в различные группы хобби.
Итак, у меня есть 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, но не могу найти ответ, который мне подходит. Благодарю.
Это не будет работать так, как вы ожидаете, из-за того, как CakePHP извлекает данные.
В зависимости от того, как вы настроите свои отношения, случится так, что Cake будет первый выберите хобби и затем сделать еще один запрос для хобби групп.
Поэтому любая сортировка, которую вы применяете ко второму запросу, будет в целом бесполезной и будет потеряна, когда эти данные будут сопоставлены со списком хобби.
Так что у тебя есть
SELECT hobbies....
Затем будет выдан еще один выбор
SELECT hooby_groups WHERE hobby_id IN [list of ids ] ORDER BY hobby_groups_id
Данные из второго выбора будут сопоставлены с первым, так что ваш заказ не так много!
В зависимости от того, какую версию CakePHP вы используете, вы можете сделать несколько вещей:
Определите отношения для использования INNER JOIN
Стратегия так позволит избежать создания двух SELECT
заявления. Таким образом, order by
причина отсортирует все данные, как вы ожидаете. Предостережение заключается в том, что с INNER JOIN
Хобби, с которыми не связана ни одна группа, никогда не будет выбрано вашим разбиением на страницы.
Если вы используете CakePHP 2.x, вы можете посмотреть на Пользовательский запрос нумерации страниц и создайте запрос так, как вам нужно, чтобы он работал.
Если вы используете CakePHP 3.x, у вас есть конструктор запросов, и Paginator может разбивать на страницы любой запрос, поэтому вы можете выполнять там свои внутренние объединения.
Чтобы помочь вам, вы можете использовать DebugKit
из CakePHP, чтобы увидеть, какие фактические запросы выполняются и как настройка этого параметра влияет на то, как генерируется запрос. Вы увидите, где order by
применяется и почему это может не работать.
В CakePHP 2.x вы можете использовать type
контролировать, как осуществляется соединение. Вам нужно использовать INNER
Других решений пока нет …