CakePHP Paginate Сортировка по содержанию данных - PullRequest
0 голосов
/ 11 мая 2018

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

Итак, у меня есть 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, но не могу найти ответ, который мне подходит. Спасибо.

1 Ответ

0 голосов
/ 11 мая 2018

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

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

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

Итак, у вас есть

SELECT hobbies....

Затем будет выдан другой выбор

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

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

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

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

  2. Если вы используете CakePHP 2.x, вы можете взглянуть на Custom Query Pagination и построить запрос так, как вам нужно, чтобы он работал.

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

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

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

...