Navigation

Laravel

How to Use `when()` for Conditional Queries

Build dynamic Laravel queries with when() method. Add conditions to queries based on request parameters without messy if statements.

Problem: You need to build queries with optional conditions based on user input, but using multiple if statements makes your code messy and hard to read.

Solution:

// Basic when() usage
$users = User::query()
    ->when($request->status, function ($query, $status) {
        return $query->where('status', $status);
    })
    ->when($request->role, function ($query, $role) {
        return $query->where('role', $role);
    })
    ->get();

// With default value (else condition)
$posts = Post::query()
    ->when($request->category_id, 
        function ($query, $categoryId) {
            return $query->where('category_id', $categoryId);
        },
        function ($query) {
            return $query->whereNull('category_id');
        }
    )
    ->get();

// Complex conditions
$products = Product::query()
    ->when($request->search, function ($query, $search) {
        $query->where(function ($query) use ($search) {
            $query->where('name', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
        });
    })
    ->when($request->min_price && $request->max_price, function ($query) use ($request) {
        return $query->whereBetween('price', [$request->min_price, $request->max_price]);
    })
    ->when($request->sort === 'price', function ($query) use ($request) {
        return $query->orderBy('price', $request->direction ?? 'asc');
    })
    ->paginate(20);

// Works with relationships
$users = User::with(['posts' => function ($query) use ($request) {
    $query->when($request->published_only, function ($query) {
        return $query->where('published', true);
    });
}])->get();

Why it works: when() only executes the callback if the first parameter is truthy. This eliminates the need for if statements around query building. The optional second callback runs when the condition is falsy, perfect for default behaviors.

Pro tip: Chain multiple when() calls for clean, readable query building. Great for search filters and API endpoints with optional parameters.

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Laravel