In this Tutorial, we will see how to Filter Records using a BelongsToMany Relationship in Livewire. This is the part 6 of the Series related to adding New Functionality to a Table using Livewire. In Last Part of the Series we implemented Filter on the BelongsTo column of the Product Model using Livewire.
Lets say our Product Model has belongsToMany
Relationship with Category as follows
public function categories()
{
return $this->belongsToMany(Category::class);
}
That means there is a Category Table which holds all the Categories. And then there is a Pivot Table which links Products and Categories. And we want to Filter using Category, so when the User selects a Category we will display only those Products which are related to that Category.
First of all we will fetch all the Categories. We would create a categories
property and populate it in the mount method.
$this->categories = Category::pluck('name', 'id')->toArray();
And in the View, we would create the dropdown by looping through these categories
.
<div>
<label>
Categories
</label>
<select>
<option value="">Any</option>
@foreach($categories as $category_id => $category_name)
<option value="{{$category_id}}">{{$category_name}}</option>
@endforeach
</select>
</div>
The Dropdown will have all the Categories that User can select from. As usual we also have an Any
option so as to display all the Products.
Next we will create a property called $selectedCategory
and link it with above dropdown using wire:model
.
<select wire:model="selectedCategory">
....
....
</select>
This way whenever User changes the above Dropdown, the property $selectedCategory
would be updated in the Component and Livewire will re-render the component. Now all we need to do is to change the Query to reflect the value of Selected Category.
Below is the current Query that we have.
public function query()
{
return Product::query()
->when($this->selectedStatus, function($query) {
return $query->where('status', $this->selectedStatus);
})
->when($this->selectedBrand, function($query) {
return $query->where('brand_id', $this->selectedBrand);
});
}
We will include another when
Condition and we would filter the records using whereHas
Clause like below:
->when($this->selectedCategory, function($query) {
return $query->whereHas('categories', function($query) {
return $query->where('categories.id', $this->selectedCategory);
});
});
Go ahead and test it, our Filter should be working now. So unlike the previous Filters where we were able to apply the Query directly on the Product Model
, here we had to pass a Closure to whereHas
in order to Filter using BelongsToMany
Relation.
If you have liked this Tutorial, please checkout the Livewire Package tall-crud-generator which automatically generates all the Code related to applying Filter on a BelongsToMany Relation.
Top comments (0)