Laravel: What is the purpose of the `loadMissing` function?
I believe the accepted answer is missing one important fact that may mislead some: you cannot run loadMissing($relation)
on a collection.
This is important because most use cases of lazy eager loading relationships are when you already have a collection and you don't want to commit the n+1 sin - i.e. unnecessarily hit the DB multiple times in a loop.
So while you can use load($relation)
on a collection, if you only want to do it if the relationships haven't already been loaded before, you're out of luck.
Very useful for APIs
The use of with
, loadMissing
or load
can has more importance when use it in API environment, where the results are passed to json
. On this case, lazy loading hasn't any effect.
Very good question; there are subtle differences which are not getting reflected instantly by reading through the documentation.
You are comparing "Lazy Eager Loading" using loadMissing()
to "Lazy Loading" using magic properties on the model.
The only difference, as the name suggests, is that:
- "Lazy loading" only happens upon the relation usage.
- "Eager lazy loading" can happen before the usage.
So, practically, there's no difference unless you want to explicitly load the relation before its usage.
It also worths a note that both load
and loadMissing
methods give you the opportunity to customize the relation loading logic by passing a closure which is not an option when using magic properties.
$book->loadMissing(['author' => function (Builder $query) {
$query->where('approved', true);
}]);
Which translates to "Load missing approved author if not already loaded" which is not achievable using $book->author
unless you define an approvedAuthor
relation on the model (which is a better practice, though).
To answer your question directly; yeah, there won't be any difference if you remove:
$book->loadMissing('author');
in that particular example as it's being used right after the loading. However, there might be few use cases where one wants to load the relation before its being used.
So, to overview how relation loading methods work:
Eager loading
Through the usage of with()
you can "eager load" relationships at the time you query the parent model:
$book = Book::with('author')->find($id);
Lazy eager loading
To eager load a relationship after the parent model has already been retrieved:
$book->load('author');
Which also might be used in a way to only eager load missing ones:
$book->loadMissing('author');
Contrary to the load()
method, loadMissing()
method filters through the given relations and lazily "eager" loads them only if not already loaded.
Through accepting closures, both methods support custom relation loading logics.
Lazy loading
Lazy loading which happens through the usage of magic properties, is there for developer's convenience. It loads the relation upon its usage, so that you won't be needing to load it beforehand.
@rzb has mentioned a very good point in his answer as well. Have a look.