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

For a while many of us used to write conditional 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: click here to watch video version of this lesson for free, in my 4-hour online-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();

// From Laravel 5.4 you can pass the same condition value as a parameter
$query->when(request('role', false), function ($q, $role) { 
    return $q->where('role_id', $role);
});

$authors = $query->get();

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

More information about conditional queries: https://laravel.com/docs/5.5/queries#conditional-clauses

Here’s a pull request for the parameter acceptance (not mentioned in official docs): https://github.com/laravel/framework/pull/18419

Like our articles?
Check out our Laravel online courses!

2 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here