Clean Relationship Filtering in Laravel Using withWhereHas()

Filter and eager load relationships in one expressive query.

  • 30 Apr, 2026
  • 9 Views

Clean Relationship Filtering in Laravel Using withWhereHas()

In Laravel, when working with relationships, you often need to:

  • Filter parent models
  • Load only specific related records

Laravel provides a clean solution: withWhereHas().

🔹 Basic Usage

User::withWhereHas('orders', function ($q) {
    $q->where('status', 'paid');
})->get();

👉 This will:

  • Return users who have paid orders
  • Load only those paid orders

🔹 Using with Multiple Conditions

User::withWhereHas('orders', function ($q) {
    $q->where('status', 'paid')
      ->where('amount', '>', 1000);
})->get();

👉 Filters both user and related orders together.

🔹 Real Project Example

Imagine showing users with premium purchases:

$users = User::withWhereHas('orders', function ($q) {
    $q->where('plan', 'premium');
});

Now:

  • Only users with premium orders are returned
  • Only premium orders are loaded

🔹 Nested Relationship Usage

User::withWhereHas('orders.items', function ($q) {
    $q->where('type', 'digital');
})->get();

👉 Works even for deeper relationships.

🎯 Why Use withWhereHas()

  • Keeps conditions in one place
  • Avoids duplication
  • Improves readability
  • Reduces mistakes in queries

🧠 When to Use It

Use it when:

  • Filtering relationships
  • Eager loading with conditions
  • Building APIs with relational data

Share: