Laravel вывод продуктов из дочерней и родительской категорий

В CategoryController есть метод в котором формируется массив с родительской и дочерними категориями.

public function show($slug)
    {
        $category = Category::where('slug', $slug)->with('childrenCategories')->get()->toArray();
        // dd($category);
        $products = $category->products()->orderBy('id', 'desc')->all();
        
        return view('category', compact('category', 'products'));
    }

"Category::where('slug', $slug)->with('childrenCategories')->get()->toArray();" формирует следующий массив

array:1 [▼
  0 => array:9 [▼
    "id" => 1
    "title" => "Молочные продукты"
    "category_id" => null
    "children_categories" => array:2 [▼
      0 => array:9 [▼
        "id" => 2
        "title" => "молоко"
        "category_id" => 1
        "slug" => "moloko"
        "categories" => []
      ]
      1 => array:9 [▼
        "id" => 3
        "title" => "творог"
        "category_id" => 1
        "slug" => "tvorog"
        "categories" => []
      ]
    ]
  ]
]

а далее выдает ошибку.

Метод products() в модель Category следующий:

  public function products()
    {
        return $this->hasMany(Product::class);
    }

Помогите пожалуйста правильно сформировать $products = $category->products()->orderBy('id', 'desc')->all(); для передачи во view.

(прошу прощения если неправильно где-то сформировал мысль)


Ответы (1 шт):

Автор решения: Yauhen Kib

Вот пример рекурсии, которая вернет все дочерние категории (с любой глубиной вложенности), дальше останется получить только товары из этих категорий.

class Category extends Model
{

    // ...

    public function children(): HasMany
    {
        return $this->hasMany(Category::class, 'parent_id', 'id');
    }

    public function getAllChildren(): Collection
    {
        $allChildren = collect();
        $this->appendChildren($allChildren, $this);

        return $allChildren;
    }

    protected function appendChildren(Collection &$collection, $category): Collection
    {
        foreach ($category->children as $child) {
            $collection->add($child);
            $collection = $this->appendChildren($collection, $child);
        }

        return $collection;
    }
    
    public function getAllProducts()
    {
        $categoryIds = $this->getAllChildren()->pluck('id')->toArray();
        array_push($categoryIds, $this->id);

        return Product::whereIn('category_id', $categoyIds)->get();
    }

Наверное не самый оптимальный вариант, но рабочий..

→ Ссылка