PHP
Querying Parent Models Based on Related Model Conditions
Filter parent Eloquent models by applying conditions to their related child models using `whereHas`, `orWhereHas`, and `doesntHave` for precise data retrieval.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// --- Usage Examples ---
// Get users who have at least one post with "Laravel" in its title
$usersWithLaravelPosts = User::whereHas('posts', function ($query) {
$query->where('title', 'like', '%Laravel%');
})->get();
// Get users who have posts published after a certain date
$usersWithRecentPosts = User::whereHas('posts', function ($query) {
$query->where('created_at', '>', now()->subDays(7));
})->get();
// Get users who have a post with 'Laravel' AND a post with 'Eloquent'
// This implies two separate posts (or one post matching both)
$usersWithBothKeywords = User::whereHas('posts', function ($query) {
$query->where('title', 'like', '%Laravel%');
})->whereHas('posts', function ($query) {
$query->where('title', 'like', '%Eloquent%');
})->get();
// Get users who DO NOT have any posts
$usersWithoutPosts = User::doesntHave('posts')->get();
// Get users who have posts with 'Laravel' OR who have no posts at all
$usersWithLaravelOrNoPosts = User::whereHas('posts', function ($query) {
$query->where('title', 'like', '%Laravel%');
})->orDoesntHave('posts')->get();
How it works: This snippet demonstrates how to query parent models based on conditions of their related models. The `whereHas()` method allows you to add constraints to the existence of a related model, or to conditions within that related model. `doesntHave()` filters for parents that have *no* related children, while `orWhereHas()` and `orDoesntHave()` provide flexible OR conditions. This is powerful for filtering data without loading all related records into memory.