PHP
Filtering Models Based on Related Records with `whereHas`
Learn to filter parent models by the existence or absence of specific related records using Eloquent's `whereHas` and `whereDoesntHave` methods, improving query precision.
use App\Models\User;
use App\Models\Post;
// Get all users who have at least one published post
$usersWithPublishedPosts = User::whereHas('posts', function ($query) {
$query->where('is_published', true);
})->get();
// Get all users who do NOT have any posts at all
$usersWithoutPosts = User::doesntHave('posts')->get();
// Get all users who do NOT have any *published* posts
$usersWithoutPublishedPosts = User::whereDoesntHave('posts', function ($query) {
$query->where('is_published', true);
})->get();
// Example output
echo "Users with published posts:
";
foreach ($usersWithPublishedPosts as $user) {
echo "- {$user->name}
";
}
echo "Users without any posts:
";
foreach ($usersWithoutPosts as $user) {
echo "- {$user->name}
";
}
echo "Users without published posts:
";
foreach ($usersWithoutPublishedPosts as $user) {
echo "- {$user->name}
";
}
How it works: Eloquent's `whereHas` method is used to filter parent models based on the existence of related models that satisfy certain conditions. It's akin to an `INNER JOIN` with a `WHERE` clause on the joined table. Conversely, `doesntHave` retrieves parent models that have no related records, and `whereDoesntHave` filters for parent models that have no related records matching a specific set of conditions. These methods are crucial for complex relational data filtering.