PHP
Filter Records Based on Related Model Existence in Eloquent
Efficiently filter parent models based on the existence or absence of related records using Eloquent's `whereHas()` and `doesntHave()` methods for precise data retrieval.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\Post;
use Illuminate\Http\Request;
class QueryingRelationsController extends Controller
{
public function filterByRelationships()
{
// Get all users who have at least one post
$usersWithPosts = User::has('posts')->get();
echo "Users with at least one post: " . $usersWithPosts->pluck('name')->implode(', ') . "
";
// Get all posts that have comments containing 'great'
$postsWithGreatComments = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', '%great%');
})->get();
echo "Posts with 'great' in comments: " . $postsWithGreatComments->pluck('title')->implode(', ') . "
";
// Get all users who do NOT have any posts
$usersWithoutPosts = User::doesntHave('posts')->get();
echo "Users without any posts: " . $usersWithoutPosts->pluck('name')->implode(', ') . "
";
// Get all posts that do NOT have any comments from user ID 1
$postsWithoutCommentsFromUser1 = Post::whereDoesntHave('comments', function ($query) {
$query->where('user_id', 1);
})->get();
echo "Posts without comments from User 1: " . $postsWithoutCommentsFromUser1->pluck('title')->implode(', ') . "
";
return "Relationship filtering complete. Check console/logs.";
}
}
// In your User model (App\Models\User.php):
// public function posts()
// {
// return $this->hasMany(Post::class);
// }
// In your Post model (App\Models\Post.php):
// public function comments()
// {
// return $this->hasMany(Comment::class);
// }
How it works: Eloquent provides powerful methods to query models based on the existence or non-existence of related models. `has('relation')` retrieves parent models that have at least one related record. `whereHas('relation', function($query){...})` adds custom constraints to the related query. Conversely, `doesntHave('relation')` fetches parent models with no related records, and `whereDoesntHave('relation', function($query){...})` allows custom non-existence constraints. These methods are crucial for complex data filtering and reporting.