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