Можно ли пересобрать коллекцию?
Есть модель Category и модель Product. Между этими моделями связь многие-ко-многим. На странице категории мы получаем все товары этой категории и к каждому товару все его категории.
Пример.
$category->type
$category->name
@foreach ($category->products as $product)
$product->name
@foreach ($product->categories as $category)
$category->type
$category->name
@endforeach
@endforeach
На выходе получаем.
Manufacturer
Alize
Alize Lana Gold
Manufacturer
Alize
Country
Turkey
Fiber
Acrylic
Каждая категория имеет свой тип. Например: Country, Manufacturer или Fiber. Категория страны, производителя или состава. Country и Manufacturer у товара всегда один, а вот Fiber может быть много.
Можно ли как-то пересобрать (не знаю как правильно сказать) коллекцию, чтобы товар возвращался со всеми категория, к которым он принадлежит?
То есть, чтобы можно было сделать так.
$category->type
$category->name
@foreach ($category->products as $product)
$product->country // категория
$product->manufacturer // категория
$product->name
@foreach ($product->fibers as $fiber) // категория
$fiber->name
@endforeach
@endforeach
Мы явно пишем Country, Manufacturer и только Fiber перебираем в массиве т.к у товара может быть много категорий этого типа.
Ответы (1 шт):
Во-первых, Вы явно что-то странное делаете, если Country, Manufacturer и Fiber это некие категории, которые belongsToMany, которые зачастую нужны вам как belongsTo, не проще сделать их отдельными моделями?
Теперь по существу. Я вижу для вас 2 варианта.
1 вариант: Getters в модели Product
Просто добавляем геттерсы в модель, которые будут искать внутри коллекций наших отношений.
public function getCountryAttribute()
{
return $this->categories->firstWhere('type', 'country');
}
public function getManufacturerAttribute()
{
return $this->categories->firstWhere('type', 'manufacturer');
}
public function getFibersAttribute()
{
return $this->categories->where('type', 'fibers');
}
2 вариант: Relations в модели Product
С fibers просто добавляем условие к нашему отношению:
public function fibers()
{
return $this->categories()->where('type', 'fibers');
}
С country и manufacture сложнее. Здесь можно использовать hasOneThrough отношение (https://laravel.com/docs/8.x/eloquent-relationships#has-one-through), чтобы получать отношение сквозь пивотную (belongsToMany) таблицу, однако здесь придётся создать пивотную модель для пивотной таблицы.