Filters in Laravel with OOP Practices
By: Ashish Shakya
Tags: Oop Concepts, Scalability, Hacks, Laravel, Filters

Basically, to implement the resource filter API, we check the query parameters from the existing request and apply the corresponding query bindings (where clause) to our Model .

The normal way to implement the filter criteria seems like:

The normal way to return the filtered data for a resource.

This approach of returning filtered data would be applicable for small-sized applications only. If the application is booted with heavy sets of filter logic then we would have to add recurring IF logic in the controller itself. This makes our controller very bulky.

Now let's implement some OOP principles to extract and encapsulate the logic to its own separate classes.

First, we create an abstract class named BaseFilter . We then add a apply() method with some logic inside it as shown below. We shall discuss its working mechanism later in this blog.

2. Create a separate filter class for integrating filter logic for a resource that extends the BaseFilter class. Before we had included the filter logic using nested IFs in the Controller class but now we extract them into individual methods.

Things to remember:

The name of the method must be the key of the query parameters of the URL.

The method name must be written in camelCase .

. For eg, if the URL is some-url?ward=20&municipality=2 and we have to filter the resource by ward and municipality, then we need to create two methods naming ward() and municipality() respectively.

3. We then add a local scope in the Model class. This method accepts an instance of Eloquent Builder as a first parameter and sets of filters as the second parameter. It simply instantiates the FilterClass which we had defined before in Step 2 and calls its apply() method.

4. Lastly, we can simply call the filterBy scope of our Model class and pass all the query parameters as its arguments.

What is happening behind the scene?

First, in the controller class, we are returning the resource by binding the local scope to our builder (filterBy) which we had created in the model class. As a parameter, we pass the array of query parameters using request()->all() .

which we had created in the model class. As a parameter, we pass the array of query parameters using . The filterBy scope then instantiate the FilterClass and calls its apply() method. Keep in mind that, when we instantiate the FilterClass , we need to pass the instance of query builder and the previous array of query parameters for the filters.

scope then instantiate the and calls its method. Keep in mind that, when we instantiate the , we need to pass the instance of query builder and the previous array of query parameters for the filters. The filter class that we had created extends the BaseFilter class. It includes individual methods where the logic for the filter is written.

class. It includes individual methods where the logic for the filter is written. The apply() method of the BaseFilter class is built in such a way that it iterates over every query parameter from the current URL and calls the filter method defined in its subclasses.

method of the class is built in such a way that it iterates over every query parameter from the current URL and calls the filter method defined in its subclasses. These methods are later responsible for binding the where clause in the Eloquent builder.