What is difference between:
->whereHas('user', function($user){
$user->where('age', '>', 21);
})
and
->with(['user' => function($user){
$user->where('age', '>', 21);
}])
apart from that with method causes eager loading?
CodePudding user response:
As you said, With
causes eager loading but doesn't restrict/filter the results.
WhereHas
doesn't eager load the user model but restricts/filters the results.
Imagine a Blogs model that can have a user or not.
WhereHas
will query for models with a user meeting the requirements and only return models that do.
With
will query for all blog models but only include the user when it meets the requirement.
Three blog posts
id: 1
user: { id: 1, age: 25 }
title: blog post 1
id: 2
user: null
title: blog post two without user
id: 3
user: { id: 3, age: 15 }
title: blog post 2 with user low age
This
Blog::whereHas('user', function($user){
$user->where('age', '>', 21);
})->get()
will return you
id: 1
user: null
user_id: 1
title: blog post 1
While
Blog::with(['user' => function($user){
$user->where('age', '>', 21);
}])->get()
Will return you
id: 1
user: { id: 1, age: 25 }
user_id: 1
title: blog post 1
id: 2
user: null
user_id: null
title: blog post 2 without user
id: 3
user: null
user_id: 3
title: blog post 2 with user low age
You would most likely be using the two together, like this, restricted to fetch only blog posts by users over the age of 21, and eager load the user model on those, without the restriction since results are already limited for it in the whereHas.
Blog::whereHas('user', function($user){
$user->where('age', '>', 21);
})->with('user');