Laravel文档中Eager Loading section的第一句话是:



在本节的最后一段中指出:


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

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

但是我看不到$book->loadMissing('author')的目的。它在这里做什么?

如果我只删除此行,会有什么区别?根据第一句话,无论如何,$book->author->name中的作者还是会被延迟加载,对吧?

最佳答案

很好的问题;存在细微的差异,无法通读文档立即反射(reflect)出来。

您正在在模型上将使用Lazy Eager Loading的“ loadMissing() ”与使用magic properties的“延迟加载”进行比较。

顾名思义,唯一的区别是:

  • “延迟加载”仅在关系使用时发生。
  • 在使用之前可能会发生“急懒加载”。

  • 因此,实际上,除非您想在使用关系之前显式加载该关系,否则没有任何区别。

    还值得一提的是,loadloadMissing方法都为您提供了通过传递闭包来定制关系加载逻辑的机会,而闭包在使用魔术属性时是不可行的。

    $book->loadMissing(['author' => function (Builder $query) {
        $query->where('approved', true);
    }]);
    

    转换为“如果尚未加载,则加载缺少的已批准作者”,除非您在模型上定义$book->author关系,否则使用approvedAuthor是无法实现的(不过,这是一种更好的做法)。

    直接回答您的问题;是的,如果您删除以下内容,则不会有任何区别:

    $book->loadMissing('author');
    

    在该特定示例中,因为它是在加载后立即使用的。但是,可能很少有用例希望在使用关系之前先加载该关系。

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

    渴望加载

    通过使用 with() ,您可以在查询父模型时“急于加载”关系:

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

    懒惰的渴望加载

    为了急于在之后加载关系,已经获取了父模型:

    $book->load('author');
    

    也可以用这种方式只渴望加载丢失的那些:

    $book->loadMissing('author');
    

    load() 方法相反, loadMissing() 方法过滤给定的关系,并且仅当尚未加载
    时才“急切”加载它们

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

    延迟加载

    通过使用magic properties会发生延迟加载,这是为了方便开发人员。它会根据使用情况加载关系,因此您无需事先加载它。

    @rzb在his answer中也提到了一个很好的观点。看一看。

    关于php - Laravel: `loadMissing`函数的作用是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47238937/

    10-10 18:51