Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here
Tutorial Free

Eloquent::when(): No More if-elses for Conditional Queries

October 04, 2017
2 min read

Tutorial last revisioned on June 05, 2025 with Laravel 12

Many of us are used to write conditional Eloquent queries with "if-else", something like this:

if (request('filter_by') == 'likes') {
$query->where('likes', '>', request('likes_amount', 0));
}
if (request('filter_by') == 'date') {
$query->orderBy('created_at', request('ordering_rule', 'desc'));
}

What if I told you there's a (much) better way? Easily readable and more Laravel-ish. Meet when() method.

$query = Author::query();
 
$query->when(request('filter_by') == 'likes', function ($q) {
return $q->where('likes', '>', request('likes_amount', 0));
});
$query->when(request('filter_by') == 'date', function ($q) {
return $q->orderBy('created_at', request('ordering_rule', 'desc'));
});
 
$authors = $query->get();

Looks nicer, doesn't it?


Notice: you can read more Eloquent tips in my course Eloquent: Expert Level


Wait, there's more

In the example below we will filter users only if the role was passed as a request option.

This means - as long as there is no parameter or it's false/null - you will see all of the users. But if it becomes a value, lets say "1" for administrator - you will only see administrators.

$query = User::query();
 
$query->when(request('role', false), function ($q, $role) {
return $q->where('role_id', $role);
});
 
$authors = $query->get();

What about default values?

Below example shows third argument to the when() method. This closure will only execute if the first argument evaluates as false.

Author::query()
->when(request('filter_by') == 'likes', function ($q) {
return $q->where('likes', '>', request('likes_amount', 0));
}, function ($q) {
return $q->orderBy('created_at', request('ordering_rule', 'desc'));
})->get();

It's not just a prettier way to write the same "IF" but is also a great way to organize conditional queries.

You can find more information about conditional queries in the Laravel docs

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Comments & Discussion

M
MattLab ✓ Link copied!

Very nice tip, thanks !

MH
Mahmudul Haque ✓ Link copied!

Learn something new thank you sir

SA
Shino Aburame ✓ Link copied!

Looks nicer, doesn't it?

Actually, no. I don't understand why it's so complicated, to use an additional function where you can just "if ", complicating the readability of the code.

D
DaveB ✓ Link copied!

I have to agree with Shino. The only advantage I see to this extra complexity is a reduction of duplicated code when the query chains get very long. Otherwise it's a nightmare for readability IMO, compared to the simple if/else.

PD
Prashant Dhungana ✓ Link copied!

Today I learnt something valuable. My query was something like this:

  • $query->when($request->min_price , function ($q) use ($min_price, $max_price) { $q->whereBetween('price', [ $min_price, $max_price ]); });*

This used to return all of the data. It seemed like this filter was not used.

The important lesson here is, When we directly use $request->min_price, then it replaces the exact value of the min price. And suppose the min_price is 0. Since laravel uses if conditions for when statements, the if condition became false (0). And hence the query was not executed.

The proper method was as to use request('min_price') or $request->has('min_price)

��
Виталий Маркелов ✓ Link copied!

This is actually the best part of this self-promotional piece of original author arrogance (one can safely replace last three words with "shit"). Thank you, Prashant.

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.