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