Как использовать "group by" с полиморфными отношениями в Laravel?

У меня есть следующее соотношение:

return $this->morphedByMany('App\Models\Movie', 'listable', 'cnt_lists', 'list_id')->withPivot('id', 'order', 'updated_at')->where('movies.has_poster', true)->orderBy('order', 'desc')->withTimestamps();

Это отношение создает этот запрос:

select `movies`.*, `cnt_lists`.`list_id` as `pivot_list_id`, `cnt_lists`.`listable_id` as `pivot_listable_id`, `cnt_lists`.`id` as `pivot_id`, `cnt_lists`.`order` as `pivot_order`, `cnt_lists`.`updated_at` as `pivot_updated_at`, `cnt_lists`.`created_at` as `pivot_created_at` from `movies` inner join `cnt_lists` on `movies`.`id` = `cnt_lists`.`listable_id` where `movies`.`has_poster` = '1' and `cnt_lists`.`list_id` in ('3176', '3283', '3285', '3287') and `cnt_lists`.`listable_type` = 'App\Models\Movie' order by `order` desc

Это отношение работает, но оно захватывает много для каждого списка. Я пытаюсь ограничить только один список. Первоначально я изучал take(), но это ограничивает весь набор результатов, а не лимит списка. Затем я подумал, что могу группировать cnt_lists.list_id, который будет захватывать по одному в списке. Похоже, мне кажется, что я ищу. Ниже приведен запрос, который работает для меня, я просто пытаюсь понять, как использовать группу в отношениях, потому что он нарушает отношения, когда я добавляю его.

select `movies`.*, `cnt_lists`.`list_id` as `pivot_list_id`, `cnt_lists`.`listable_id` as `pivot_listable_id`, `cnt_lists`.`id` as `pivot_id`, `cnt_lists`.`order` as `pivot_order`, `cnt_lists`.`updated_at` as `pivot_updated_at`, `cnt_lists`.`created_at` as `pivot_created_at` from `movies` inner join `cnt_lists` on `movies`.`id` = `cnt_lists`.`listable_id` where `movies`.`has_poster` = '1' and `cnt_lists`.`list_id` in ('3176', '3283', '3285', '3287') and `cnt_lists`.`listable_type` = 'App\Models\Movie' group by `cnt_lists`.`list_id` order by `order` desc

Когда я добавляю groupBy в соотношение:

return $this->morphedByMany('App\Models\Movie', 'listable', 'cnt_lists', 'list_id')->withPivot('id', 'order', 'updated_at')->where('movies.has_poster', true)->groupBy('cnt_lists.list_id')->orderBy('order', 'desc')->withTimestamps();

Я получаю следующую ошибку:

select `movies`.*, `cnt_lists`.`list_id` as `pivot_list_id`, `cnt_lists`.`listable_id` as `pivot_listable_id`, `cnt_lists`.`id` as `pivot_id`, `cnt_lists`.`order` as `pivot_order`, `cnt_lists`.`updated_at` as `pivot_updated_at`, `cnt_lists`.`created_at` as `pivot_created_at` from `movies` inner join `cnt_lists` on `movies`.`id` = `cnt_lists`.`listable_id` where `movies`.`has_poster` = 1 and `cnt_lists`.`list_id` in (3176, 3283, 3285, 3287) and `cnt_lists`.`listable_type` = App\Models\Movie group by `cnt_lists`.`list_id` order by `order` desc

По какой-то причине модель App\Models\Movie не находится в кавычках, поэтому она разбивает весь запрос. Если я запускаю запрос вручную, он работает, мне просто нужно добавить кавычки к полиморфной модели. т.е. "App\Models\Movie"

Ответ 1

Итак, выясняется, что проблема связана с строгим режимом MySQL, который включает в себя режим ONLY_FULL_GROUP_BY.

Я отключил строгий режим на уровне Laravel, и теперь запрос работает так, как ожидалось. Просто установите для параметра strict в false в файле конфигурации базы данных для вашего соединения.

'strict' => false,

Ответ 2

У меня есть ур вопрос и ответ. Согласно вашему ответу, я понимаю, что основной проблемой является "Строгий режим", который на самом деле является только списком режимов 5.7 по умолчанию. Некоторое время наши люди не понимают о strict mode. В https://mattstauffer.co/blog/strict-mode-and-other-mysql-customizations-in-laravel-5-2 эту ссылку вы узнаете, как Enabling and disabling strict mode in Laravel 5.2 например.

Эти настройки находятся в файле config/database.php в разделе connections.mysql. Для начала давайте рассмотрим включение и отключение "строгого" режима:

 'connections' => [
        'mysql' => [
            // Behave like MySQL 5.6
            'strict' => false,

            // Behave like MySQL 5.7
            'strict' => true,
        ]
    ]

Также мы можем настроить его:

'connections' => [
        'mysql' => [
            // Ignore this key and rely on the strict key
            'modes' => null,

            // Explicitly disable all modes, overriding strict setting
            'modes' => [],

            // Explicitly enable specific modes, overriding strict setting
            'modes' => [
                'STRICT_TRANS_TABLES',
                'ONLY_FULL_GROUP_BY',
            ],
        ]
    ]

Спасибо