Laravel(雄辩)访问器:仅计算一次


Laravel (eloquent) accessors: Calculate only once

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

模型作业有一些与用户关联的作业应用程序我想了解用户是否已经申请了工作。

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

有没有简单的方法只计算一次访问器

/**
 * 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();
}

提前谢谢。

正如评论中所建议的那样,真的一点也不棘手

 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;
    } 

}

我会在你的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);
您可以将

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),它将反映这一点,这意味着它将返回该值而不执行任何其他操作。