
Laravel when(): умовні запити без зайвих if
Як використовувати when() для умовних фільтрів, передавати значення в callback, додавати else через третій аргумент і не потрапляти в пастку з falsy значеннями.
when() дає змогу залишити optional filters усередині одного query chain замість того, щоб розривати побудову запиту окремими if.
Але його користь не закінчується простою заміною if. Callback може отримати саме значення умови, третій аргумент працює як else, а falsy значення на кшталт 0 потребують окремої уваги.
Базове використання when()
$query = User::query(); if ($status) { $query->where('status', $status);} $users = $query->get();$users = User::query() ->when( $status, fn ($query, $status) => $query->where('status', $status), ) ->get();У callback Laravel передає не тільки builder. Другим параметром callback можна отримати значення, передане першим аргументом у when(). Завдяки цьому не потрібен окремий use ($status).
User::query() ->when( $status, fn ($query, $status) => $query->where('status', $status), );Третій аргумент when() - це else
Повна форма when($value, $callback, $default) має другий callback. Він виконується, коли перший аргумент має falsy значення. Це дозволяє виразити if / else без виходу з fluent chain.
User::query() ->when( $sortByVotes, fn ($query) => $query->orderBy('votes'), fn ($query) => $query->orderBy('name'), ) ->get();Пастка: 0 та інші falsy значення
Product::query() ->when( $minPrice, fn ($query, $minPrice) => $query->where('price', '>=', $minPrice), );Product::query() ->when( $minPrice !== null, fn ($query) => $query->where('price', '>=', $minPrice), );when() не обмежується where()
Product::query() ->when( $categoryId, fn ($query, $categoryId) => $query->where('category_id', $categoryId), ) ->when( $onlyAvailable, fn ($query) => $query->where('stock', '>', 0), ) ->when( $sortByPrice, fn ($query) => $query->orderBy('price'), )when() зручний там, де умова модифікує той самий builder: можна умовно додавати where(), orderBy(), joins, selects та інші частини запиту.
Не потрібно замінювати ним кожен if. Якщо окрема умова читається простіше поза chain, звичайний if залишається нормальним рішенням. Для зворотної умови в Laravel також є unless().




