Making the advanced search query with Eloquent-Builder in Laravel

We needed an advanced search system in the recent project. This system included many filters that required a flexible and scalable search system.
I decided to implement a package for this system that you can see it in the GitHub and use it in your project.

What's the problem?

The problem is that you will encounter with a set of filters that you must check for a lot of conditions to add to the query.
Writing a lot of terms will surely reduce the readability of your code and slow down the development process.
Also, you can only use the filters and terms in the same scope and they will not be reusable.

But the Solution

You must Refactor your code!
To solve this problem, you need to Refactor your code by replacing many of your conditionals with Polymorphism.
Click here to learn more about this design pattern.

Practical Example:

Suppose we want to get the list of the users with the requested parameters as follows:
http://dev.to/api/users/search?age_more_than=25&gender=male&has_published_post=true
The Requested parameter will be as follows:
[ 
  'age_more_than' => '25',
  'gender' => 'male',
  'has_published_post' => 'true',
]
In the legacy code the method written below was followed:
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(Request $request)
{
$users = User::where('is_active', true);
if ($request->has('age_more_than')) {
$users->where('age', '>', $request->age_more_than);
}
if ($request->has('gender')) {
$users->where('gender', $request->gender);
}
if ($request->has('has_published_post')) {
$users->where(function ($query) use ($request) {
$query->whereHas('posts', function ($query) use ($request) {
$query->where('is_published', $request->has_published_post);
});
});
}
return $users->get();
}
}
view rawUserController.php hosted with ❤ by GitHub
We check out a condition for each request parameter.
In the future, we will have more parameters that should be checked and applied in the code above that causes us to have a dirty code.

Use the Eloquent-Builder

After installing the package presented,change your code as follows:
<?php
namespace App\Http\Controllers;
use App\User;
use EloquentBuilder;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(Request $request)
{
$users = EloquentBuilder::to(
User::class,
$request->all()
);
return $users->get();
}
}
view rawUserController.php hosted with ❤ by GitHub
You just send the model and parameters to ‘to’ method.Then, you need to define the filter for each parameter that you want to add to the query.
So easy!

Defining a filter

For example, I’ll implement one of the above example filters. Follow the example below:
<?php
namespace App\EloquentFilters\User;
use Fouladgar\EloquentBuilder\Support\Foundation\Contracts\Filter;
use Illuminate\Database\Eloquent\Builder;
class AgeMoreThanFilter implements Filter
{
/**
* Apply the age condition to the query.
*
* @param Builder $builder
* @param mixed $value
*
* @return Builder
*/
public function apply(Builder $builder, $value): Builder
{
return $builder->where('age', '>', $value);
}
}

For more details check out the GitHub repository.

GitHub logo mohammad-fouladgar eloquent-builder

Provides an Eloquent Query Builder for Laravel or Lumen.

Provides a Eloquent query builder for Laravel or Lumen

Build Status Coverage Status StyleCI Latest Stable Version Total Downloads License
This package allows you to build eloquent queries, based on request parameters It greatly reduces the complexity of the queries and conditions, which will make your code cleaner.

Basic Usage

Suppose you want to get the list of the users with the requested parameters as follows:
//Get api/user/search?age_more_than=25&gender=male&has_published_post=true
[
    'age_more_than'  => '25',
    'gender'         => 'male',
    'has_published_post' => 'true',
]
In the legacy code the method written below was followed:
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
    public function index(Request $request)
    {
        $users = User::where('is_active', true);

        if ($request->has('age_more_than')) {
            $users->where('age', '>', $request
Good luck and thank you for sharing your valuable time with me.
Happy Coding!

Post a Comment

0 Comments