laravel with() method versus load() method

laravel eager loading
laravel load relationship with condition
laravel load multiple relations
laravel relationship with condition
laravel eager load relationship
laravel wherehas morph
laravel eager loading not working
laravel load with select

I really tried to understand the difference between the with() method and the load() method, but couldn't really understand.

As I see it, using the with() method is "better" since I eager load the relation. It seems that if I use load() I load the relation just as if I would use the hasMany() (or any other method that relates to the relation between objects).

Do I get it wrong?

Both accomplish the same end results—eager loading a related model onto the first. In fact, they both run exactly the same two queries. The key difference is that with() eager loads the related model up front, immediately after the initial query (all(), first(), or find(x), for example); when using load(), you run the initial query first, and then eager load the relation at some later point.

"Eager" here means that we're associating all the related models for a particular result set using just one query, as opposed to having to run n queries, where n is the number of items in the initial set.


Eager loading using with()

If we eager load using with(), for example:

$users = User::with('comments')->get(); 

...if we have 5 users, the following two queries get run immediately:

select * from `users`
select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5)

...and we end up with a collection of models that have the comments attached to the user model, so we can do something like $users->comments->first()->body.


"Lazy" eager loading using load()

Or, we can separate the two queries, first by getting the initial result:

$users = User::all();

which runs:

    select * from `users`

And later, if we decide that we need the related comments for all these users, we can eager load them after the fact:

$users = $users->load('comments');

which runs the 2nd query:

    select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5)

...and we end up with the same result, just split into two steps. Again, we can call $users->comments->first()->body to get to the related model for any item.


Why use load() vs. with()? load() gives you the option of deciding later, based on some dynamic condition, whether or not you need to run the 2nd query. If, however, there's no question that you'll need to access all the related items, use with(). (The docs also reference a caching benefit to using load(), but I'm not familiar with that; in fact, I believe the results of load() are not cacheable.)


The alternative to either of these would be looping through the initial result set and querying a hasMany() relation for each item. This would end up running n+1 queries, or 6 in this example. Eager loading, regardless of whether it's done up-front with with() or later with load(), only runs 2 queries.

Laravel Eager Loading, When using route model binding, load() is your friend. level 2 Laravel Eloquent when() method is crazy, say goodbye to if-else. Instead of using if and else  In fact, they both run exactly the same two queries. The key difference is that with() eager loads the related model up front, immediately after the initial query (all(), first(), or find(x), for example); when using load(), you run the initial query first, and then eager load the relation at some later point.

@damiani Explanied difference between load() and with() as well but he said load() is not cacheable so I wanna say couple words about it.

Let assume we have a blog post and related with comments. And we're fetching together and caching it.

$post = Cache::remember("post.".$slug,720,function()use($slug){
   return Post::whereSlug($slug)->with("comments")->first();
});

But if there is a new comment and we want to display it immediately, we have to clear post cache and fetch post and comments together again. And that causes unnecessary queries. Lets think there are another queries for tags, media, contributors of the post etc. it will increase amount of resource usage..

public function load($relations)
{
    $query = $this->newQueryWithoutRelationships()->with(
        is_string($relations) ? func_get_args() : $relations
    );

    $query->eagerLoadRelations([$this]);

    return $this;
}

As you can see above when we use the method it loads given relation and returns model with fetched relation. So you can return it outside of a callback.

$post = Cache::remember("post.".$slug,720,function()use($slug){
   return Post::whereSlug($slug)->first();
});

$post = Cache::remember("post.relation.images.".$slug,720,function()use($post){
  return $post->load("images");
});

$post = Cache::remember("post.relation.comments".$slug,720,function()use($post){
   return $post->load("comments");
});

So if we load them seperatly, next time when some of them updated all you need to do clear specific relation cache and fetch it again. No need to fetch post, tags, images etc. over and over.

Eloquent: Relationships - Laravel, While defining database relationships in an object-oriented way Laravel's ORM​, called Eloquent, makes it trivial to eager load models, Edit your .env values to match your database or choice. I've only provided the up() method because Laravel will generate the down() automatically for new tables. Eloquent relationships are defined as methods on your Eloquent model classes. Since, like Eloquent models themselves, relationships also serve as powerful query builders, defining relationships as methods provides powerful method chaining and querying capabilities. For example, we may chain additional constraints on this posts relationship:

As @damiani said, Both accomplish the same end results—eager loading a related model onto the first. In fact, they both run exactly the same two queries. The key difference is that with() eager loads the related model up front, immediately after the initial query (all(), first(), or find(x), for example); when using load(), you run the initial query first, and then eager load the relation at some later point.

There is one more difference between With() & load(), you can put the conditions when using with() but you can't do the same in case of load()

For example:

ProductCategory::with('children')
        ->with(['products' => function ($q) use($SpecificID) {
            $q->whereHas('types', function($q) use($SpecificID) {
                $q->where('types.id', $SpecificID)
            });
        }])
        ->get(); 

Laravel eager loading - load() vs. with() : laravel, What I did was, in my controller in show method I eager loaded products like this: public function index() { $users = User::with(['products'])->paginate(5); return https://laravel.com/docs/5.4/eloquent-relationships#eager-loading Please sign in or create an account to participate in this conversation. Learn how to optimize your related model queries in Laravel with eager loading. We will set up some example relationships and then walk through how queries change with and without eager loading. I like to get my hands directly on code and experiment with things, and I hope to illustrate how eager loading works with some examples will further help you understand how to …

Optimize Laravel Eloquent Queries with Eager Loading, In Laravel, with() is used to eager load the data, while has() is used to check if You will use the has() method to check if the Post has any comments to display. What is the best practice, Laravel with Eloquent or Laravel with MySQL stored  It’s pretty simple: just load the right view. Edit: This article was written around the time of Laravel 5.2. Sometime around the release of Laravel 5.3, this method got renamed to login

Proper way to load relationship data, The Eloquent (ORM) in laravel is working amazingly and provide very simple ways for accessing to the database. public function houses() { we can use load method to load the relationship data under specific condition  The lists method on the Collection, query builder and Eloquent query builder objects has been renamed to pluck. The method signature remains the same. That's ok, rename refactoting from lists() to pluck() isn't a problem. But what with useful pluck() method which was in L5.0 and L5.1? From the 5.0 documentation: Retrieving A Single Column From

What is the difference between with and has in Laravel?, (did you edit your first post to use $with or did I just misread it entirely on the first go?) I now have to included my own loadOnly() method in my applications. [​5.5] Method load($relation) in Eloquent\Collection should use  Helpers. Introduction; Available Methods; Introduction. Laravel includes a variety of global "helper" PHP functions. Many of these functions are used by the framework itself; however, you are free to use them in your own applications if you find them convenient.

Comments
  • Thanks! I still have a question, why would I ever not use eager loading then and use the normal hasMany() method? (I think that a solution for my answer is that whenever I'm dealing with one user only, it doesn't matter whether I'm using the eager loading or not since it's gonna run 2 queries anyways?)
  • It depends on what data you're after. If you are only interested in the related model—comments, in our example—then simply query the hasMany() relation method: $users = User::find(1)->comments;, which would return only information about the comments, not the user. If, however, you also needed to access data from the initial model—the user—then $user = User::where('id','1')->with('comments')->get(); will give you a collection that includes data from the User table and their related Comments. Either way, 2 identical queries are run, but the resulting collections are different.
  • Can load be nested like with can be? Like here - stackoverflow.com/questions/47048804/…