Have you ever experienced make an advanced search page in programming? if your answer is yes maybe you know this feature has many conditions to make a query database.Especially when you are using a relational DB as MySQL in your project at that time our task will getting hard. I was searching for it. Eventually, I found a clean way to implement this feature in the Laravel project.
The main problem is that you will make many conditions for every situation. Writing a lot of terms will surely reduce the readability of your code and increase the possibility of make a mistake.
Suppose we want to get the list of the users with the requested parameters as follows:
The Request parameter will be as follows:
[ 'age_more_than' => '24', 'gender' => 'male', 'created_at' => '25-09-2019', ]
Implement this feature in
We check out a condition for each request.
In the future, if your project will need more filter requests at that time you should add many conditions to the above code. Imagine some of the queries may be advanced therefore your code to be like Monster!
Everything began from just a tutorial video called
Eloquent Techniques in laracast. It was about a new way to make an advanced filter by use of the query string. It has to separate layer filters from controller and model. It made an Eloquent query by the use of a query string. Advanced Eloquent rescued the readability of your code by a filter class. It was very good but you had to make a method for every condition. It's boring for a creative developer. You don't have a dynamic query and you have to write many methods for per condition just in a separate layer.
Imagine you will install a package composer and make a query by query string without write where for every condition. Actually you just enter query string according to the principles of that package. Therefore the package will make every condition by the query string. If you want to write a custom query in the separated layer you can do it. You can set fields of your model to allow build queries by the query string. Note that the query string must be sync with the fields of your Model. Isn't great in your opinion !?. This package saves your time and your code. Fortunately like package eloquent-filter is rare in GitHub.
-NOTE THAT : we've released the Eloquent filter version 2 recently. We suggest to installing version 2 with the new features you can visit this link : https://dev.to/mehdifathi/introduce-eloquent-filter-2-in-laravel-12g5
Run the Composer command
$ composer require mehdi-fathi/eloquent-filter:1.6.9
Add Filterable trait to your models and set fields that you will want a filter in whitelist. You can override this method in your models.
You can set
* char for filter in all fields as like below example:
private static $whiteListFilter = ['*'];
You just pass the data blade form to query string or generate a query string in the controller method. For example:
/email@example.com SELECT ... WHERE ... email = 'firstname.lastname@example.org' /users/list?first_name=mehdi&last_name=fathi SELECT ... WHERE ... first_name = 'mehdi' AND last_name = 'fathi' /users/list?username=ali&username=ali22&family=ahmadi SELECT ... WHERE ... username = 'ali' OR username = 'ali22' AND family = 'ahmadi'
You can set any operator MySQL in the query string.
/users/list?count_posts[operator]=>&count_posts[value]=35 SELECT ... WHERE ... count_posts > 35 /users/list?username[operator]=!=&username[value]=ali SELECT ... WHERE ... username != 'ali' /users/list?count_posts[operator]=<&count_posts[value]=25 SELECT ... WHERE ... count_posts < 25
You can set special parameters
orderBy in query string for make query by that.
/users/list?f_params[limit]=1 SELECT ... WHERE ... order by `id` desc limit 1 offset 0 /users/list?f_params[orderBy][field]=id&f_params[orderBy][type]=ASC SELECT ... WHERE ... order by `id` ASC limit 10 offset 0
If you are going to make a query whereBetween. You must fill the keys
end in the query string. you can set it on query string as you know.
/users/list?created_at[start]=2016/05/01&created_at[end]=2017/10/01 SELECT ... WHERE ... created_at BETWEEN '2016/05/01' AND '2017/10/01'
/users/list?count_posts[operator]=>&count_posts[value]=10&username=ali&username=mehdi&family=ahmadi&created_at[start]=2016/05/01&created_at[end]=2020/10/01 &f_params[orderBy][field]=id&f_params[orderBy][type]=ASC select * from `users` where `count_posts` > 10 and `username` in ('ali', 'mehdi') and `family` = ahmadi and `created_at` between '2016/05/01' and '2020/10/01' order by 'id' asc limit 10 offset 0
Just note that fields of query string be the same rows table database in
$whiteListFilter in your model or declare the method in your model as the override method. The overriding method can be considered custom query filter.
If you are going to make yourself a query filter you can do it easily. You just make a trait and use it on model:
Note that fields of query string be the same methods of a trait. Use the trait in your model:
/users/list?username_like=a select * from `users` where `username` like %a% order by `id` desc limit 10 offset 0
You can make every filter with eloquent-filter. If you think the eloquent-filter is useful so give a ⭐️ to that by click in the link
For more details check out GitHub repository
Good luck and thank you for sharing your valuable time with me. I hope the Eloquent Filter is useful for your code. If you have any idea or opinion I glade to know it.