Изменение выборки из таблицы, модель которой в зависимости “hasMany” Laravel 8
У меня есть модель Product и таблица Products. Так же есть связанная таблица и модель ProductImage через hasMany.
Модель Product
public function productimage()
{
return $this->hasMany(ProductImage::class);
}
И теперь когда я делаю выборку например
$prod=Product::get(); А затем во вью через @foreach перебираю их, а когда дело доходит до картинок то использую связь: @foreach($prod->productimage as $img), то выводятся все картинки. Но так же у менять есть карточка товара, для который не нужны все картинки, а только первая, для этого у меня в таблице ProductImages предусмотрено поле position, так вот, как мне её реализовать, пробовал через муттаторы, но что то не получилось:
Модель ProductImage
public function getCardImgAttribute() {
return ProductImages::where('position', 1)->get();
}
А во вью через {{$img->card_img}} выводится массив вместо одной ссылки на изображение:
src="/img/products/[{"path":"img_1.jpg"},{"path":"img_6.jpg"},{"path":"img_10.jpg"},{"path":"img_16.jpg"}]".
По идее должна выводиться ссылка для каждого элемента, а получилось что в каждом элементе 4 ссылки.
Я понимаю, что нигде не указал поле "path", которое отвечает за ссылку, я не могу понять, где я его должен указать. Что то типа {{$img->card_img->path}} не работает.
Помогите исправить, пожалуйста.
Ответы (1 шт):
public function getCardImgAttribute() {
return ProductImages::where('position', 1)->get();
}
У вас в этом коде допущена логическая ошибка, этот метод будет возвращать коллекцию из всех ProductImages у которых position = 1 а не связаных с данным объектом.
В таком случае, вы можете сделать еще одно отношение hasOne в объекте Product
таким образом
public function cardImage()
{
return $this->hasOne(ProductImage::class)->where('position', 1);
}
Далее юзать его таким образом:
$product = Product::query()->first();
dd($product->cardImage->path);
Так же второй вариант: Суть в том, чтобы из коллекции всех картинок выбрать ту, у которой position = 1
public function cardImage()
{
return $this->productimage->find(function(ProductImages $image) {
return 1 === $image->position;
});
}
Во втором случае, не будет дополнительного запроса к базе данных. Если одновременно вам нужно использовать методы cardImage и productImage тогда лучше использовать второй вариант ибо в таком случае будет лишь один запрос к базе данных. В инном случае лучше первый, запрос к базе все равно один, но каждый ваш экземпляр product будет дополнительно держать в памяти еще и коллекцию из ProductImages, при том что нужно лишь один элемент. Но это только когда вы дойдете до оптимизации производительности.