mehri abbasi
mehri abbasi

Reputation: 155

how show nested relation in laravel resource

I have Category Model that has one to many relation with itself.

It means each category has many children and each child has many products.

Now, I want to show parent categories (it means parent_id is null) with all products (list of products of all children).

Each product has category_id that category is child.

What is the best way to handle this in Laravel resources?

Category Model

class Category extends Model
{
    public function products()
    {
        return $this->hasMany('App\Models\Products', 'category_id', 'id');
    }

    public function children()
    {
        return $this->hasMany('App\Models\Category', 'parent_id', 'id');
    }
}

My Query:

$categories = Category::select(['id', 'name'])
            ->where('parent_id', '=', null)
            ->with(['children' => function ($query){
                $query->select(['id']);
                $query->with('products:id,title,description,banner');
            }])
            ->orderBy('id', 'desc')
            ->get();

And Resource:

public function toArray($request)
    {
        return [
            'id' => $this->id,
            'category' => $this->name,
            'products' => [],
        ];
    }

I tried many different ways to show products, none of them has worked so far.

Upvotes: 2

Views: 765

Answers (1)

mehri abbasi
mehri abbasi

Reputation: 155

I used hasManyThrough relation to get all product of each main category

Relation function:

public function childrenproducts() {
        return $this->hasManyThrough( Product::class, Category::class , 'parent_id', 'category_id' );
    }

Query:

$categories = Category::select(['id', 'name'])
            ->where('parent_id', '=', null)
            ->has('childrenproducts', '>=', 1)
            ->with(['childrenproducts' => function ($query) {
                $query->select(['products.id', 'products.title', 'products.description', 'products.banner']);
                $query->orderBy('products.id', 'desc');
            }])
            ->orderBy('id', 'desc')
            ->get();

Resource:

public function toArray($request)
    {
        return [
            'id' => $this->id,
            'category' => $this->getName(),
            'products' => ProductResource::collection($this->whenLoaded('childrenproducts'))
        ];
    }

Upvotes: 1

Related Questions