PHP
Filtering Parent Records by Related Model Conditions
Discover how to use Laravel Eloquent's `whereHas` and `orWhereHas` methods to efficiently filter parent records based on specific conditions applied to their related models.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
}
// Usage in a controller or elsewhere:
// Get all posts that have at least one comment
$postsWithComments = Post::has('comments')->get();
// Get all posts that have comments containing the word 'great'
$postsWithSpecificComments = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', '%great%');
})->get();
// Get posts that either have comments or are published
$postsConditional = Post::query()
->whereHas('comments', function ($query) {
$query->where('created_at', '>', now()->subWeek());
})
->orWhere('is_published', true)
->get();
// Using 'orWhereHas' to combine conditions
$postsOrWhereHas = Post::where('is_featured', true)
->orWhereHas('comments', function ($query) {
$query->where('rating', '>', 4);
})
->get();
How it works: The `whereHas` method allows you to filter results based on the existence of a relationship and conditions applied to that related model. It's incredibly useful when you need to retrieve parent records only if their associated child records meet certain criteria. `orWhereHas` provides similar functionality but combines conditions with an OR operator. This approach avoids loading all related models into memory, leading to more efficient queries, especially with large datasets.