У меня есть модель Post, и я пытаюсь ->paginate()
, ->groupBy()
и ->orderBy()
.
public function index() { $posts = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->paginate(5); // dd($posts); }
поpublic function index() { $posts = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->paginate(5); // dd($posts); }
Между тем данные в базе данных выглядят следующим образом:
| id | verified | topic | publisher_id | body | created_at | | 25 | 1 | Forest | 3 | EE | 10.12.50 | | 24 | 1 | Forest | 3 | DD | 10.11.40 | | 23 | 1 | Forest | 3 | CC | 10.10.30 | | 22 | 1 | Dance | 2 | BB | 9.50.50 | | 21 | 1 | Dance | 2 | AA | 9.40.40 | | 20 | 1 | Music | 1 | ZZ | 9.30.30 | | 19 | 1 | Music | 1 | XX | 9.20.20 | | 18 | 1 | Art | 1 | YY | 9.10.10 | | 17 | 1 | Art | 1 | WW | 9.00.00 | | 16 | 1 | Ski | 2 | KK | 7.00.00 |
Когда я раскомментирую dd()
и запускаю код, я получаю этот журнал:
LengthAwarePaginator { ... items : { items : { 0 => Post{..} 1 => Post{..} 2 => Post{..} 3 => Post{..} ... } } ... }
0 => Post{#249} : "published_by: "3", "body": "CC", "created_at": "10.10.30"
1 => Post{#250} : "published_by: "1", "body": "XX", "created_at": "9.20.20"
2 => Post{#251} : "published_by: "1", "body": "WW", "created_at": "9.00.00"
3 => Post{#252} : "published_by: "2", "body": "KK", "created_at": "7.00.00"
Это выглядит странно по какой-то причине. Он сделал groupBy
для пользователя-3, но не для других. Кроме того, он потянет самое раннее, созданное, а не последнее. Изменение desc
to asc
like ->orderBy('created_at', 'asc')
полностью вывело бы из строя.
Другими словами, возвращая 'CC' for user-3, Forest
вместо 'EE' for user-3, Forest
Тогда я подумал, что, возможно, это ->paginate(5)
.
public function post() { $posts = Post::where... ... ->paginate(5); $postsTry = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->get(); // dd($postsTry); }
поpublic function post() { $posts = Post::where... ... ->paginate(5); $postsTry = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->get(); // dd($postsTry); }
Я получаю коллекцию только с такими items
как над ним. ( 0 => Post{..}, 1 => Post{..}, 2 => Post{..}
).
Он группирует данные как самые ранние сначала, а не последние сначала . Что мне не хватает? Что я делаю неправильно?
Чтобы завершить, обратите внимание, что я хочу получить:
'EE' for user-3, Forest
'BB' for user-2, Dance
'ZZ' for user-1, Music
'YY' for user-1, Art
Убрал мой предыдущий ответ, но все равно будет включать примечание от Laravel Pagination о groupBy()
с помощью paginate()
.
Примечание. В настоящее время операции с
groupBy
поgroupBy
которые используют операторgroupBy
не могут эффективно выполняться Laravel. Если вам нужно использоватьgroupBy
сgroupBy
на страницы набором результатов, рекомендуется запросить базу данных и создать файл-указатель вручную.
ОБНОВИТЬ
Из-за вашего необычного формата даты для поля created_at
вам понадобятся целочисленные значения cast
ed, которые будут использоваться правилом order by
statement (как целое, а не строка). Вот рабочий пример:
Post::selectRaw("*, CAST(REPLACE(created_at, '.', '') AS UNSIGNED INTEGER) ca") ->where('verified', '1') ->orderBy('ca', 'desc') ->groupBy('topic', 'publisher_id') ->paginate();
Вам нужно будет использовать подзапрос (или другой метод соединения), чтобы получить верхний элемент в вашей группе. См. Раздел « Получение строк», удерживающих групповой максимум определенного столбца
Удалил мой пример.