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
Very nice tip, thanks !