PHP
Filtering Models Based on Related Records with `has` and `whereHas`
Discover how to filter parent models in Laravel Eloquent based on the existence or specific attributes of their related child records using `has()` and `whereHas()`.
// Get all posts that have at least one comment
$postsWithComments = App\Models\Post::has('comments')->get();
// Get all users who have at least 5 posts
$usersWithManyPosts = App\Models\User::has('posts', '>=', 5)->get();
// Get all posts that have at least one approved comment
$postsWithApprovedComments = App\Models\Post::whereHas('comments', function ($query) {
$query->where('is_approved', true);
})->get();
// Get all users who have posts published after a certain date
$usersWithRecentPosts = App\Models\User::whereHas('posts', function ($query) {
$query->where('published_at', '>', now()->subDays(7));
})->get();
// Get posts that do NOT have any comments
$postsWithoutComments = App\Models\Post::doesntHave('comments')->get();
// Get posts that do NOT have any approved comments
$postsWithoutApprovedComments = App\Models\Post::whereDoesntHave('comments', function ($query) {
$query->where('is_approved', true);
})->get();
How it works: The `has()` and `whereHas()` methods in Laravel Eloquent provide powerful ways to query parent models based on the existence or specific conditions of their related child models. `has()` checks for the mere existence of at least one related record, while `whereHas()` allows you to add specific constraints to the related query. These methods are crucial for building complex filters and ensuring your queries are efficient when dealing with relationships, also demonstrated are `doesntHave()` and `whereDoesntHave()` for inverse filtering.