quyle92 liked this thread
Eager loading is not required when using ->first() because you are requiring only one related model.
Example :
Parent Model : User One to Many Relation with Model : Posts (One to many)
//...We have 20 posts form user 1
Without Eager loading
$posts = User::find(1)->posts(); // 21 Queries
With Eager loading
$posts = User::find(1)->with('posts')->posts(); // 2 Queries
##Now try the same with ->first()
Without Eager loading
$posts = User::find(1)->posts()->first(); // 2 Queries
With Eager loading
$posts = User::find(1)->with('posts')->posts()->first(); // 2 Queries
I havent't checked it but its supposed to work this way !
mcraz said:
You are a bit wrong ;)
First off to answer OP question:
$model->relation // dynamic property -> lazy loads the relation, returns Collection
$model->relation() // returns Relation Object, thus operates on the relation query, nothing is loaded now
$model->relation()->first(); // runs as relation query ->first(), doesn't load the relation at all
// first here is a method on the Query Builder
$model->relation->first(); // loads the related models and fetches first from the collection
// while this time first is the method on the Collection
// You can also lazy load the relation like this:
$model->load('relationName');
Now about the eager loading:
$posts = User::find(1)->posts(); // no queries at all for the posts
$posts = User::find(1)->posts; // lazy loads posts (2 queries)
// the same as
$posts = User::with('posts')->find(1)->posts; // 2 queries as well
$posts = User::find(1)->with('posts')->posts(); // ERROR, no 'posts' method on the query builder
Eager loading is supposed to avoid n+1 issue, which occurs when you do this:
$users = User::take(10)->get();
foreach ($users as $user) {
$user->posts; // this runs query for each user = 11 queries
}
// eager loading:
$users = User::with('posts')->take(10)->get(); // 2 queries
// or lazy loading on the Collection, doing the same as above
$users = User::take(10)->get();
$users->load('posts');
// then in that foreach loop no queries will be run,
// because posts were already matched to the users and are accessible on $user->posts;
So no need to eager load anything if you work with single parent (User in the example).
quyle92 liked this reply
Thank you very much for the detailed answers!
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community