'laravel with() method versus load() method

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?



Solution 1:[1]

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(); 

Solution 2:[2]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Radhe Shyam sharma
Solution 2 Teoman T?ng?r