Как запросить связь, используя данные из модели в качестве условия?

#laravel #relationship

#laravel #связь

Вопрос:

У меня есть модель сотрудника, которая имеет одну модель позиции. Модель должности имеет множество отношений модели заработной платы.:

Сотрудник назначается на «должность» (например, разработчик программного обеспечения) Должность имеет много окладов, в зависимости от многолетнего опыта

В модели employee есть поле «опыт» для указания лет опыта

Я хочу получить зарплату для этого сотрудника с учетом его должности и многолетнего опыта

Я пытаюсь что-то вроде:

(в моей позиционной модели):

 public function salaryForExperienceYears($years)
  {
    return $this->hasOne(Salary::class)
                ->where('experience', $years)
                ->first()
                ->salary
                ;
  }
  

(в моем контроллере, где я хочу получить информацию):

 $employee->position->salaryForExperienceYears(1);
  

если я жестко закодирую «1» для числа лет, это логично работает.
но я хочу использовать многолетний опыт этого сотрудника, и я не могу этого сделать:

 $employee->position->salaryForExperienceYears($employee->experience);
  

Как мне это сделать?

Даже если я смогу найти способ сделать это, используя эту структуру, кажется, что есть лучший способ сделать это … потому что «опыт» уже является свойством в $employee …

точно так же, как у меня есть связь для -> position, которая «ограничивает» результаты, используя поле position_id, доступное в $employee , кажется, что должен быть способ, при котором поле experience также «выводится из контекста» здесь (хотя это не связь в другой таблице)

Может быть, мне следует использовать какой-то другой тип отношений?

Ответ №1:

Попробуйте это:

 $experience = $employee->experience;
$employee->position->salaryForExperienceYears($experience);
  

Комментарии:

1. да, это работает, спасибо. Но все же кажется, что должен быть «более элегантный» способ сделать это, не так ли? в конце концов, вы передаете свойство из $employee внутри каскадного вызова, который начинается, именно, с этого $employee … как-то кажется излишним…

Ответ №2:

Используйте leftJoin в salaryForExperienceYears:

 public function salaryForExperienceYears()
{
    return $this->hasOne(Salary::class)
                ->where('experience', new Expression('years'))
                ->lefftJoin('employees', 'id', 'employees_id')
                ->first()
                ->salary
                ;
}
  

Или

 $position = $employee->position;
$selary = $position->salaryForExperienceYears($employee->experience);