Я пытаюсь использовать промежуточную таблицу для обозначения спонсорских отношений между двумя различными пользовательскими таблицами (сотрудник & Non-Employee) со следующими требованиями:
Я заметил, что полиморфные отношения для Laravel поддерживают только отдельные ассоциации. Обычно они используют промежуточную таблицу во взаимосвязи, чтобы избежать необходимости создавать несколько таблиц с одной и той же подписью. В моем случае мне нужно полиморфировать обе стороны отношений, поскольку в любой момент я мог иметь спонсора / спонсора, принадлежащего к любой таблице. Я не уверен, правильно ли я поступаю, в какой-то момент в тупике.
Вот что у меня сейчас есть:
Employees
id
sponsor_id
NonEmployees
id
sponsor_id
Sponsors
id
sponsorable_id
sponsorable_type
Далее я настраиваю следующие модели:
Модели / Employee.php
public function sponsors() {
return $this->morphMany('Sponsor', 'sponsorable');
}
Модели / NonEmployee.php
public function sponsors() {
return $this->morphMany('Sponsor', 'sponsorable');
}
Модели / Sponsor.php
public function sponsorable() {
return $this->morphTo();
}
С помощью этой настройки я смог выполнить общие запросы к таблице Sponsors, а затем выполнить обратный инжиниринг, чтобы получить имя спонсора.
Sponsor::with('sponsorable')->get();
Sponsor::find(1)->sponsorable;
Я пришел к следующей идее использовать существующую Полиморфную Отношения для обработки нескольких ассоциаций.
Сначала я изменил схему так:
Employees
id
NonEmployees
id
Sponsors
id
sponsored_id
sponsored_type
sponsorable_id
sponsorable_type
Итак, я удалил поле спонсор_ид из каждой таблицы типов учетных записей и добавил второе полиморфное отношение в таблицу Спонсоров.
Я обновил модели следующим образом:
Модели / Employee.php & Модели / NonEmployee.php
public function sponsorable()
{
return $this->morphOne('Sponsor', 'sponsorable');
}
public function sponsors()
{
return $this->morphMany('Sponsor', 'sponsor');
}
Модели / Sponsor.php
public function sponsor()
{
return $this->morphTo();
}
public function sponsorable()
{
return $this->morphTo();
}
Теперь, так как Laravel не поддерживает тип отношений morphManyThrough (), вы заметите, что я изменил некоторые имена функций, чтобы он стал немного чище при использовании отношений, так как мне нужно переходить из одной таблицы через промежуточная таблица, а затем к 3-й таблице, чтобы получить информацию, которую я хочу.
С этой структурой я могу сделать следующее:
$employee = Employee::find(2)->sponsorable->sponsor; // Gets employee's sponsored party
$sponsors = $employee->sponsors; // Gets individual that the employee is sponsoring.
foreach ($sponsors as $sponsor)
echo $sponsor->sponsorable->first_name;
$employee->sponsors()->save(new Sponsor()); // New sponsor
$non_employee->sponsors()->save(new Sponsor()); // New sponsor
Я также могу выполнить обратный поиск:
Sponsor::find(1)->sponsor->first_name; // Sponsoring party
Sponsor::find(1)->sponsorable->first_name; // Party being sponsored
Других решений пока нет …