Writing clean, composable Eloquent Filters

Composing Query Builders with Functions 😎

Ikechi Michael
Jun 4, 2018 · 3 min read

If you’ve been following my medium publications on Laravel, you’d know my journey started about 6 months ago. In this time, I have learned loads about PHP, Laravel, Eloquent, Query Builders, and much more.

In this post, I’ll be introducing a method I use at work to make filtering and sorting collections easy. Thanks, Michalis Antoniou for showing me this.


“Why re-invent laravel filters? 😱”, you might ask.

No, I’m not trying to. A lot of filter composition happens on the projects I work on. The code needs to be able to filter by this and that, and sort by this other parameter too.


For the sake of this article, I’ll be assuming you have worked with Laravel and have used Eloquent to work with collections.

Let’s begin 💪

Imagine that this URL and query strings:

/users?name=myk&age=21&company=rick-and-morty&sort_age=desc

automatically knew to filter the DB query by showing users that have their

  • name containing myk
  • age as 21
  • company name containing rick-and-morty

and order the user records by age in descending order.

Also, imagine that the eloquent query filter for this, looked something like:

See how each query string corresponds to a method that handles it? 😍

rather than …

this is hard on the eye, I must say 😩

The previous method presents a clean, composable, easy-to-understand approach to filtering collections in Laravel, and that’s what we’ll be learning to achieve. 🔥

Introducing QueryFilters 😍

You may have noticed that the UserFilters.php class extends QueryFilters.php, which is a base class (one we inherit from) that contains the logic that makes this type of filtering possible.

The apply(…) method holds the magic sauce 😜

The filters() method returns an associative array contain input values in the url and body of the request. So, it’ll contain query strings and their values, as well as key-values within the request body (for POST and PUT requests).

The apply(Builder $builder) method loops through the associative array returned by filters() and

  • if the inheriting class has a method with the name of the request key, it executes that method, passing it a parameter with the request value if exists.

So, how do we use this?

Introducing the Filterable Trait 😀

This trait is to be used in every Eloquent Model you intend to be filterable.

In our case, we’ll be using it in our User model like:

<?phpuse App\Filters\Filterable;class User {  use Filterable;  ...}

Let’s work on our UserController 👇

Now, within our UserController.php, or any other controller in fact, we can inject UserFilters into any method and have Laravel’s dependency injection manager fill that for us.

Here’s a simple UserController that returns a list of users via its index() method:

Now, we celebrate 🍾🎉

If you load the endpoint that UserController’s index() method serves, you should be able to use variations of the query strings in this URL:

/users?name=myk&age=21&company=rick-and-morty&sort_age=desc

and see its effect on the response. 🔥🔥🔥


I really like this approach because it allows one build really complex filters while keeping the code clean and reusable. We already have at work, and still do.

I look forward to your feedback in the comments. 😍😍😍

Ikechi Michael

Written by

I’ve learned I don’t know anything. I've also learned that people will pay for what I know. Maybe that's why they never pay.