What is the opposite of when()?
unless() is the obvious answer, and it is correct.
But there is also a quieter answer.
when() itself accepts a third callback that runs when the condition is falsy.
Most uses of when() look like this:
$query->when(
$this->customerId,
fn (Builder $query, int $customerId) => $query->where('customer_id', $customerId),
);
That covers the simple case. But what if the falsy branch also needs to do work?
Take an optional customer filter. If one was selected, scope to that customer. If not, scope to the customers the current user is allowed to see, not every row in the table.
That's exactly what the third argument to when() is for, a second callback that runs when the condition is falsy:
$query->when(
$this->customerId,
fn (Builder $query, int $customerId) => $query->where('customer_id', $customerId),
fn (Builder $query) => $query->whereIn('customer_id', Auth::user()->customers()->pluck('id')),
);
The same goes for unless(), which has the same three-argument shape with the conditions flipped.
If you are reaching for when() or unless() and finding yourself adding an outer if/else to handle the other branch, the third argument is probably what you want.
Here to help,
Aaron
P.S. Knowing the unsung arguments to everyday Laravel helpers is a community sport. Come trade your favorites with us.