我有一个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();
}
提前致谢。
答案 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
),则会反映出来,这意味着它会返回这个价值没有做任何额外的事情。