PHP
Filtering Records by Related Model Existence in Eloquent
Master filtering parent models based on the existence or absence of related records using Eloquent's `has`, `whereHas`, and `doesntHave` methods.
<?php
use App\Models\Post;
use App\Models\User;
// Get all posts that have at least one comment
$postsWithComments = Post::has('comments')->get();
// Get all users who have published at least 3 posts
$usersWithManyPosts = User::has('posts', '>=', 3)->get();
// Get all posts that have at least one approved comment
$postsWithApprovedComments = Post::whereHas('comments', function ($query) {
$query->where('approved', true);
})->get();
// Get all users who have posts with 'Laravel' in their title
$usersWithLaravelPosts = User::whereHas('posts', function ($query) {
$query->where('title', 'like', '%Laravel%');
})->get();
// Get all posts that do NOT have any comments
$postsWithoutComments = Post::doesntHave('comments')->get();
// Get all users who do NOT have any posts or whose posts are all drafts
$usersWithoutPublishedPosts = User::whereDoesntHave('posts', function ($query) {
$query->where('status', 'published');
})->get();
How it works: Eloquent offers powerful methods to filter models based on the existence or absence of related models. `has()` retrieves parent models that have at least one related record (or a specified count). `whereHas()` allows you to add constraints to the related model's query, filtering parent models only if their related records meet specific criteria. Conversely, `doesntHave()` and `whereDoesntHave()` retrieve parent models that *do not* have any related records or do not have any related records meeting certain criteria, respectively. These methods are crucial for complex filtering requirements involving relationships.