I have products
, categories
, sizes
tables and also have 2 pivot tables named category_product
and product_size
in my database.
I am trying to get products belong to a specific category and I need to filter them by size.
I have tried this but I am getting all sizes…
$category = Category::where('slug', $slug)->first(); $products = $category->products() ->with('sizes') ->whereHas('sizes', function($q) use($size_id) { $q->where('size_id', '=', $size_id); }) ->paginate(12);
Product model
public function categories() { return $this->belongsToMany(Category::class); } public function sizes() { return $this->belongsToMany(Size::class); }
Category model
public function products() { return $this->belongsToMany(Product::class); }
Size model
public function products() { return $this->belongsToMany(Product::class); }
Advertisement
Answer
whereHas()
will filter the models returned based on the eager loaded relationship, but does not filter the relationship itself. If you want that, you need to pair it with the second argument of with()
like so:
$size_id = 10; $category = Category::where('slug', $slug)->first(); $products = $category ->products() ->with('sizes', fn ($q) => $q->where('size_id', $size_id)) ->whereHas('sizes', fn ($q) => $q->where('size_id', $size_id)) ->paginate(12);
So you are using the same callback twice, which is a bit silly but works to return only the desired data.