保存后的Laravel关系可用性()

时间:2016-09-15 20:45:14

标签: php laravel model eloquent relationship

我正在使用Laravel 5构建一个简单的时间跟踪应用程序,其中我有两个Laravel模型,一个名为“User”,另一个名为“Week”

关系非常简单:
Week.php:

public function user()
{
    return $this->belongsTo('App\User');
}

user.php的:

function weeks()
{
    return $this->hasMany('App\Week');
}

现在,User.php文件还有一个名为“getCurrentWeek()”的简单助手/新手函数,顾名思义,它返回当前周

function getCurrentWeek()
{
    $possibleWeek = $this->weeks->sortByDesc('starts')->all();
    if(count($possibleWeek) != 0)
    {
        return $possibleWeek[0];
    }
    else
    {
        return null;
    }
}

我的问题是:如果我为用户创建了第一周,并将其附加/关联到用户,如下所示:

$week = new Week;

//Omitted: Setting so attributes here ...

$week->user_id = $user->id;
$weeks->save()
$user->weeks()->save($week);

然后调用$user->getCurrentWeek();方法,该方法返回null,尽管已创建新周,与用户相关并已保存到数据库。在我看来,预期的行为将是getCurrentWeek()返回新创建的周 我在这里误解了Eloquent /做了什么错误?

3 个答案:

答案 0 :(得分:7)

关系属性在第一次访问时会延迟加载。加载后,它们不会自动刷新与关系中添加或删除的记录。

由于您的getCurrentWeek()函数使用了relationship属性,因此该代码将起作用:

$week = new Week;
// setup week ...
$user->weeks()->save($week);

// $user->weeks attribute has not been accessed yet, so it will be loaded
// by the first access inside the getCurrentWeek method
dd($user->getCurrentWeek());

但是,这段代码不起作用:

// accessing $user->weeks lazy loads the relationship
echo count($user->weeks);

// relate a new record
$week = new Week;
// setup week ...
$user->weeks()->save($week);

// $user->weeks inside the method will not contain the newly related record,
// as it has already been lazy loaded from the access above.
dd($user->getCurrentWeek());

您可以修改getCurrentWeek()方法以使用关系方法($this->weeks())而不是属性($this->weeks),这将始终命中数据库,或者您可以重新加载添加或删除记录后的关系(使用load()方法)。

更改getCurrentWeek()方法以使用关系方法weeks()(@Bjorn提供的更新方法)

function getCurrentWeek()
{
    return $this->weeks()->orderBy('starts', 'desc')->first();
}

或者,使用load()方法刷新关系:

// accessing $user->weeks lazy loads the relationship
echo count($user->weeks);

// relate a new record
$week = new Week;
// setup week ...
$user->weeks()->save($week);

// reload the weeks relationship attribute
$user->load('weeks');

// this will now work since $user->weeks was reloaded by the load() method
dd($user->getCurrentWeek());

答案 1 :(得分:1)

只是添加到@patricus回答......

保存/创建/更新后,您还可以清空所有缓存的关系数据,如下所示: $user->setRelation('weeks',[]);

或有选择地: $user->weeks

之后,数据将仅在需要时再次加载延迟: ii

这样你可以继续使用延迟加载。

答案 2 :(得分:0)

$user->weeks()->save($week);不需要,因为您使用$week->user_id = $user->id;手动将一周附加到用户并保存。

您实际上可以将整个功能重写为:

function getCurrentWeek()
{
    return $this->weeks->sortByDesc('starts')->first();
}

或者

function getCurrentWeek()
{
    return $this->weeks()->orderBy('starts', 'desc')->first();
}

修改

我做了一个概念验证,它的工作原理如下:

  

应用\ user.php的

function weeks()
{
    return $this->hasMany('App\Week');
}

function getCurrentWeek()
{
    return $this->weeks->sortByDesc('starts')->first();
}
  

应用\ Week.php

public function user()
{
    return $this->belongsTo('App\User');
}
  

routes / web.php或App / Http / routes.php

Route::get('poc', function () {
    $user = App\User::find(1);
    $week = new App\Week;
    $week->user_id = $user->id;
    $week->starts = Carbon\Carbon::now();
    $week->save();
    return $user->getCurrentWeek();
});
  

结果:

{
    id: 1,
    user_id: "1",
    starts: "2016-09-15 21:42:19",
    created_at: "2016-09-15 21:42:19",
    updated_at: "2016-09-15 21:42:19"
}