In my Laravel application I am building a filter function. You can filter model A by selecting what kind of relations it should have with model B. Model A has a many-to-many relation with Model B. So for example, model A1 has a relation with model B1, B2, B3, model A2 has a relation with B2, B3 and model A3 has a relation with model B3.
If you select only B3 in the filter model A1, A2 and A3 should show. If you select B3 and B2 only A1 and A2 should show.
Is there a way I could solve this issue and how? I have no idea if my example is clear, if not, please tell me.
I tried whereHas
by doing the following:
$gyms = Gym::whereHas('facilities', function (Builder $query) use ($facilities) {
$query->whereIn('id', $facilities);
})->get();
The problem is that if I want all gyms with facility 1 and facility 2 it shows gyms with only facility 1 or facility 2 but I need models that have both.
Gym is model A from my example and Facility is model B. $facilities
is an array of Facility ID's.
To have a "where in" clause in Laravel, you can use the whereIn() method.
$gyms = Gym::whereHas('facilities', function (Builder $query) use ($facilities) {
$query->whereIn('facilities.id', $facilities);
})->get();
The above will return results that match one or more of the id
s in the array. If you want to only return matches that contain all of the ids in the array you can specify this with the 3rd and 4th params of whereHas()
:
$gyms = Gym::whereHas('facilities', function (Builder $query) use ($facilities) {
$query->whereIn('facilities.id', $facilities);
}, '=', count($facilities)) //<-- This bit
->get();
The above assumes there aren't any duplicate id
s in $facilities
and that all the id
s exist in the database.