PHP
Optimize N+1 Queries with Eager Loading and Constraints
Learn how to efficiently fetch related models using Eloquent's `with()` method and add constraints to the eager-loaded relationships to avoid N+1 query problems.
// In your User model
public function posts()
{
return $this->hasMany(Post::class);
}
// Fetch users and their published posts
$users = App\Models\User::with(['posts' => function ($query) {
$query->where('is_published', true)->orderBy('created_at', 'desc');
}])->get();
// Alternative: Use whereHas to filter users who have *any* published posts
$usersWithPublishedPosts = App\Models\User::whereHas('posts', function ($query) {
$query->where('is_published', true);
})->with('posts')->get(); // Still eager load the posts for those users
foreach ($users as $user) {
echo $user->name . ' has ' . $user->posts->count() . ' published posts.';
foreach ($user->posts as $post) {
echo "- " . $post->title . "
";
}
}
How it works: This snippet demonstrates how to use Eloquent's `with()` method to eager load related models, preventing N+1 query issues. It also shows how to add constraints to the eager-loaded relationship directly within the `with()` call, ensuring only specific related records are fetched. The `whereHas()` method is also included to filter parent models based on the existence of related models that meet certain criteria, followed by eager loading those specific relations.