PHP
Efficiently Eager Load Related Models with Specific Conditions
Optimize your Laravel Eloquent queries by eager loading relationships with custom conditions, reducing N+1 problems while fetching only relevant related data.
<?php
// In app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
// In app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// Example Usage (e.g., in a controller or route)
// Eager load only published posts for each user
$usersWithPublishedPosts = App\Models\User::with(['posts' => function ($query) {
$query->where('is_published', true)->orderBy('published_at', 'desc');
}])->get();
foreach ($usersWithPublishedPosts as $user) {
echo "User: {$user->name}
";
foreach ($user->posts as $post) {
echo "- Published Post: {$post->title}
";
}
}
// Eager load posts only if they have comments
$usersWithPostsHavingComments = App\Models\User::with(['posts' => function ($query) {
$query->has('comments'); // Assuming Post model has a 'comments' relationship
}])->get();
// Eager load posts for users, but only load the posts if the user has more than 5 posts
$usersWithManyPosts = App\Models\User::with('posts')
->has('posts', '>', 5)
->get();
How it works: While eager loading (`with()`) helps solve the N+1 query problem, you often need to apply specific conditions to the eager-loaded relationships themselves. This snippet demonstrates how to constrain eager loads using a closure within the `with()` method. This allows you to filter, order, or limit the related models that are fetched, ensuring that only relevant data is loaded. You can also combine `with()` with `has()` or `whereHas()` to filter the parent models based on the existence or conditions of their relationships, providing highly optimized queries.