The first sentence of the Eager Loading section from the Laravel docs is:

将Eloquent 的关系作为属性访问时,关系 数据是"延迟加载"的.这意味着关系数据不是 在您第一次访问该属性之前实际加载.

In the last paragraph of this section it is stated:

To load a relationship only when it has not already been loaded, use the loadMissing method:

public function format(Book $book)
{
    $book->loadMissing('author');

    return [
        'name' => $book->name,
        'author' => $book->author->name
    ];
}

But I don't see the purpose of $book->loadMissing('author'). Is it doing anything here?

What would be the difference if I just remove this line? According to the first sentence, the author in $book->author->name would be lazy-loaded anyway, right?

推荐答案

很好的问题;有些细微的差异并不是通过阅读文档就能立即反映出来的.

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:

  • "延迟加载"只在关系使用时发生.
  • "Eager lazy loading" can happen before the usage.

所以,实际上,没有区别,除非您想在使用关系之前显式地加载它.

还值得注意的是,loadloadMissing方法都为您提供了定制关系加载逻辑的机会,方法是传递闭包,而在使用magic属性时,闭包不是选项.

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


直接回答你的问题;是的,如果你删除了:

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


因此,要概述关系加载方法是如何工作的:

急装

通过使用with(),您可以在查询父模型时"立即加载"关系:

$book = Book::with('author')->find($id);

Lazy eager loading

为了紧急加载关系after,父模型已经被检索:

$book->load('author');

它还可以用于仅急于加载丢失的文件的方式:

$book->loadMissing('author');

load()方法相反,loadMissing()方法过滤给定的关系并懒惰地"Eager "地加载它们only if not already loaded.

通过接受闭包,这两种方法都支持自定义关系加载逻辑.

懒惰加载

通过使用magic properties实现的延迟加载是为了方便开发人员.它在使用关系时加载关系,因此您不需要事先加载它.


@rzb在his answer篇文章中也提到了一个非常好的观点.看一看

Laravel相关问答推荐

如何让 Laravel 的 Collection 表现得像一个流?

Laravel 5 如何配置 Queue 数据库驱动程序以连接到非默认数据库?

所有 POST 请求上的 Laravel 4 CSRF

Laravel Blade - 产生内部部分

laravel url 验证变音符号

Laravel 5.4 LengthAwarePaginator

Laravel 表 * 没有名为 * 的列

Laravel 验证 - 输入必须是数组中的项目之一

如何在 AWS Elastic Beanstalk 上设置和使用 Laravel 调度?

413请求实体在laravel homestead for windows中太大的nginx服务器

如何更改 Handlebars.js 的默认分隔符?

Laravel 随机排序

如何利用 StorageFacade 的 Filesystem 类的 glob 方法?

调整行数以形成:: Textarea Laravel 5

WhereHas Laravel 中的关系计数条件是什么

如何在laravel中获取列值的平均值

使用 Queue::fake() 测试监听器

Laravel 删除集合中的第一项

Laravel Route 模型与关系绑定

Laravel 4 控制器模板/Blade - 正确的方法?