PHP
Filtering Eloquent Models Based on Related Model Existence
Discover how to use Eloquent's `has()` and `whereHas()` methods to retrieve parent models that either have or do not have related records matching specific conditions.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
class Comment extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// Find all posts that have at least one comment
// $postsWithComments = Post::has('comments')->get();
// Find all posts that have comments by a specific user (ID 1)
// $postsWithSpecificUserComments = Post::whereHas('comments', function ($query) {
// $query->where('user_id', 1);
// })->get();
// Find posts that do NOT have any tags
// $postsWithoutTags = Post::doesntHave('tags')->get();
// Find posts that do NOT have any comments by a specific user (ID 1)
// $postsWithoutSpecificUserComments = Post::whereDoesntHave('comments', function ($query) {
// $query->where('user_id', 1);
// })->get();
How it works: Eloquent's `has()` and `whereHas()` methods allow you to filter parent models based on the existence or absence of related models. `has('relation')` retrieves models that have at least one related record. `whereHas('relation', function ($query) { ... })` allows you to add additional constraints to the related query. Corresponding `doesntHave()` and `whereDoesntHave()` methods allow you to retrieve models that do not have related records or do not have related records matching specific conditions.