Существует только 2 способа решения этой проблемы:
- Либо вы вытаскиваете все товары и в конце их обрезаете (рекомендуется, только если в магазине не слишком много товаров):
$shops = Shop::with(['products' => function($subQuery) {
$subQuery
->with('pictures') //Running in scope of product, also load each product's pictures
->orderBy('created_at', 'desc');
}])
->get();
foreach ($shops as $shop) {
$shop->setRelation('products', $shop->products->take(3));
}
ПРИМЕЧАНИЕ:
Вы загрузите каждый отдельный продукт, связанный с загружаемыми вами магазинами. С этим могут возникнуть проблемы с памятью.
Возьмите только то, что вам нужно, но добавьте вопрос n + 1 (рекомендуется только при небольших количествах
$shops
:
$shops = Shop::get();
foreach ($shops as $shop) {
$shop->load([
'products' => function($query) {
$query
->orderBy('created_at', 'desc')
->limit(3)
->get();
}]);
}
ПРИМЕЧАНИЕ:
N + 1 проблема запроса: вы выполняете новый запрос для каждого магазина, поэтому, если у вас есть миллион магазинов, это будет миллион дополнительных запросов.
РЕДАКТИРОВАТЬ: (отвечая на вопрос с комментариями)
Q : Как я могу отсортировать $ магазины по их последнему продукту в поле create_at?
$sortedShops = $shops->sortBy(function ($shop, $key) {
return $shop->products->first()->created_at;
})->values()->all();
sortBy
вызывается для коллекции (не uery). Это позволяет вам go по каждому элементу (в этом "Делайте покупки в магазинах") и используйте каждый объект. Обратите внимание, что эта функция не будет работать, если у вас нет товаров, связанных с магазином.
* В конце ->values()->all()
убедитесь, что при преобразовании магазинов в json, вы создадите массив, а не объект в js.
Источник: https://laravel.com/docs/7.x/collections#method -sortby
РЕДАКТИРОВАТЬ: (удаляется исходный ответ как не работает)
- Предыдущий ответ не работает, потому что
limit(3)
ограничит общее количество d загруженных товаров вместо 3 товаров в магазине (мой плохой).