PHP
Filtering Models by Related Records Using Eloquent whereHas
Efficiently retrieve parent models based on conditions applied to their related records using Eloquent's powerful whereHas method to refine your queries.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
}
// Retrieve all posts that have at least one comment containing 'Laravel'
$postsWithLaravelComments = Post::whereHas('comments', function (Builder $query) {
$query->where('content', 'like', '%Laravel%');
})->get();
// Retrieve all posts that have no comments (or comments not matching a specific criteria)
$postsWithoutComments = Post::doesntHave('comments')->get();
// Retrieve posts that have at least 5 comments
$postsWithManyComments = Post::has('comments', '>=', 5)->get();
How it works: The `whereHas` method allows you to filter results based on the existence of a relationship and conditions applied to the related models. Instead of loading all related comments and then filtering, `whereHas` generates an efficient SQL `WHERE EXISTS` clause. This snippet shows how to find posts with comments containing a specific keyword. It also introduces `doesntHave` to find models without any related records and `has` to filter based on the count of related records, providing powerful ways to constrain queries based on relationship data.