Laravel(雄辩)访问者:只计算一次

时间:2016-02-19 14:23:45

标签: php laravel optimization eloquent accessor

我有一个Laravel模型,它有一个计算出的访问者:

模型作业有一些 JobApplications ,它们与用户相关联。 我想知道用户是否已申请工作。

为此,我创建了一个访问者user_applied,它与当前用户获得applications关系。这可以正常工作,但每次访问该字段时都会计算访问者(进行查询)。

是否有 easy 方法仅计算访问者一次

/**
 * Whether the user applied for this job or not.
 *
 * @return bool
 */
public function getUserAppliedAttribute()
{
    if (!Auth::check()) {
        return false;
    }

    return $this->applications()->where('user_id', Auth::user()->id)->exists();
}

提前致谢。

3 个答案:

答案 0 :(得分:2)

正如评论中所建议的那样,并不是很棘手

 protected $userApplied=false;
/**
 * Whether the user applied for this job or not.
 *
 * @return bool
 */
 public function getUserAppliedAttribute()
{
    if (!Auth::check()) {
        return false;
    }

    if($this->userApplied){
        return $this->userApplied;
    }else{
        $this->userApplied = $this->applications()->where('user_id', Auth::user()->id)->exists();

        return $this->userApplied;
    } 

}

答案 1 :(得分:1)

我会在你的User模型上创建一个传递Job的方法,并返回一个关于用户是否应用的布尔值:

class User extends Authenticatable
{
    public function jobApplications()
    {
        return $this->belongsToMany(JobApplication::class);
    }

    public function hasAppliedFor(Job $job)
    {
        return $this->jobApplications->contains('job_id', $job->getKey());
    }
}

用法:

$applied = User::hasAppliedFor($job);

答案 2 :(得分:0)

您可以将user_applied值设置为model->attributes数组,并在下次访问时从属性数组中返回。

public function getUserAppliedAttribute()
{
    $user_applied =  array_get($this->attributes, 'user_applied') ?: !Auth::check() && $this->applications()->where('user_id', Auth::user()->id)->exists();
    array_set($this->attributes, 'user_applied', $user_applied);
    return $user_applied;
}

第一次访问array_get时会返回null,这会导致?:的下一行被执行。 array_set会将评估值设置为'user_applied'密钥。在随后的调用中,array_get将返回先前设置的值。

这种方法的奖励优势是,如果您在代码中的某处设置user_applied(例如Auth::user()->user_applied = true),则会反映出来,这意味着它会返回这个价值没有做任何额外的事情。