У меня есть модель Laravel, у которой есть рассчитанный метод доступа:
модель работа имеет некоторые JobApplications которые связаны с пользователь.
Я хочу узнать, подал ли пользователь заявку на работу или нет.
Для этого я создал аксессор 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();
}
Заранее спасибо.
Я бы вместо этого создал метод на вашем 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);
Как предложено в комментарии и на самом деле совсем не сложно
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_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
), это будет отражать это, то есть возвращать это значение без каких-либо дополнительных действий.