phpmysqllaraveleloquentlaravel-query-builder

Laravel eloquent relationship - multiple whereHas and whereIn for different filter options


I have multiple many-to-many relationships and i want to filter through them. The models are:

I attached an screenshot:

(https://i.sstatic.net/TJPwp.png)

States are Alabama and Arizona, Districts are Autaga, Baldwin and Apache

When i check Alabama and Arizona the query works and i get the requested items. Now i only want items from Arizona and Autaga - but the query just returns items from Autaga.

$query->when($states, function ($query) use ($districts, $states) {
    $query->whereHas('states', function($query) use($states) {
        $query->whereIn('name', $states);
    });
});
$query->when($districts, function ($query) use ($districts, $states) {
    $query->where(function ($subQuery) use ($states, $districts) {
        $subQuery->whereHas('states', function($query) use($states) {
            $query->whereIn('name', $states);
        });
        $subQuery->whereHas('districts', function($query) use($districts) {
            $query->whereIn('name', $districts);
        });
    });
});

Solution

  • Because you use and logic, the result must satisfy both conditions. So use orWhere, try:

    $query->when($districts || $states, function ($query) use ($districts, $states) {
        $query->whereHas('states', function($query) use($states) {
            $query->whereIn('name', (array) $states);
        });
    
        $query->orWhere( function($query) use($districts){
            $query->whereHas('districts', function($query) use($districts) {
                $query->whereIn('name', (array) $districts);
            });
        });
    });