Support the ongoing development of Laravel.io →
Database Eloquent
Last updated 2 years ago.

quyle92 liked this thread

1

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

Suppose you want all 20 posts by 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 !

Last updated 2 years ago.
0

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).

Last updated 2 years ago.

quyle92 liked this reply

1

@jarektkaczyk Thanks for the clarification !

Last updated 2 years ago.
0

Thank you very much for the detailed answers!

Last updated 2 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.