laravel在创建父模型后急于使用with()vs load()进行加载

Yea*_*der 5 php eager-loading eloquent laravel-5 laravel-5.4

我正在创建一个Reply模型,然后尝试返回具有所有者关系的对象。这是返回空对象的代码:

//file: Thread.php
//this returns an empty object !!??
public function addReply($reply)
{
    $new_reply = $this->replies()->create($reply);
    return $new_reply->with('owner');
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我将with()方法换成load()方法以加载所有者关系,则可以得到预期的结果。那就是返回的回复对象及其相关的所有者关系:

//this works
{
    $new_reply = $this->replies()->create($reply);
    return $new_reply->load('owner');
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么。寻找澄清。

谢谢,耶

Mar*_*łek 5

这是因为您应该with在没有对象(正在查询)时使用,而在已经有对象时应该使用load

例子:

用户集合

$users = User::with('profile')->get();
Run Code Online (Sandbox Code Playgroud)

要么:

$users = User::all();
$users->load('profile');
Run Code Online (Sandbox Code Playgroud)

单用户

$user = User::with('profile')->where('email','sample@example.com')->first();
Run Code Online (Sandbox Code Playgroud)

要么

$user = User::where('email','sample@example.com')->first();
$user->load('profile');
Run Code Online (Sandbox Code Playgroud)

Laravel中的方法实现

您还可以查看with方法实现:

public static function with($relations)
{
    return (new static)->newQuery()->with(
        is_string($relations) ? func_get_args() : $relations
    );
}
Run Code Online (Sandbox Code Playgroud)

因此它会启动新查询,因此实际上只有在您使用时才会执行查询getfirst依此类推,load实现的位置如下:

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

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

    return $this;
}
Run Code Online (Sandbox Code Playgroud)

因此它返回的是同一个对象,但是会加载该对象的关系。