Search code examples
phplaraveleloquentlaravel-query-builder

Custom filtering on Eloquent model


My application supports fetching data with filters. My current implementation (which works fine) is

Model::select($fields)->with($relations)->tap(function ($query) use ($filters) {
  // A lot of filtering logic here
  // $query->where()...... 
})->get();

However, I would like to move the filtering logic directly into the Model so I could just do

Model::select($fields)
  ->with($relations)
  ->applyFilters($filters)
  ->get();

I have tried to add a filter method to the Model but at that point I'm working with a Builder and it does not recognize my function:

Call to undefined method Illuminate\Database\Eloquent\Builder::applyFilters()

Is there an easier way to do this, other than creating a new builder class and use that?


Solution

  • I figured it out! I just had to add a scopeApplyFilters to my Model class. It injects the Builder as the first parameter automatically, so the logic ends up looking like

    public function scopeApplyFilters($query, $filters)
    {
        // Perform filtering logic with $query->where(...);
    
        return $query;
    }
    

    Then I can just call it with Model::applyFilters($filters);