2015-04-15 11 views
1

Я пытаюсь использовать промежуточную таблицу для обозначения отношений между спонсорскими двумя разными таблицами пользователей (Employee & 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'); 
} 

Модели/Спонсор. PHP

public function sponsorable() { 
    return $this->morphTo(); 
} 

С помощью этой установки, я был в состоянии выполнять общие запросы подстановок к таблице спонсоров, а затем перепроектировать их, чтобы получить имя спонсора.

Sponsor::with('sponsorable')->get(); 
Sponsor::find(1)->sponsorable; 
+0

То, что вы описали в отношениях между «спонсором» и «сотрудников» выглядит как «древовидная» структура. Это верно? т. е. один сотрудник может быть «спонсором», а также «спонсироваться» другим сотрудником? –

+0

Да, это правильно. То же самое касается «не-сотрудников». По этому конкретному вопросу между ними мало различий, за исключением того, что они находятся в разных таблицах с разными схемами. Есть предположения? – Jeremy

+0

У вас есть логика для обеспечения соблюдения ваших правил? Я думаю о терминах «циклов» в «отношениях». Больше как «ориентированные графики». Что произойдет при обработке, если произойдет «цикл»? –

ответ

2

Я придумал следующую идею, чтобы использовать существующую Полиморфную связь для обработки нескольких ассоциаций.

Во-первых, я изменил схему к этому:

Employees 
id 

NonEmployees 
id 

Sponsors 
id 
sponsored_id 
sponsored_type 
sponsorable_id 
sponsorable_type 

Итак, я удалил sponsor_id поле от каждой из таблиц типа счета и добавил второй полиморфный отношения к таблице спонсоров.

Я обновил модели следующим образом:

Модели/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 Безразлично 't поддерживает тип отношения morphManyThrough(), вы заметите, что я изменил некоторые из названий функций, чтобы он читал немного более чистого при использовании relati так как я должен идти из одной таблицы через промежуточную таблицу, а затем в третью таблицу, чтобы получить нужную мне информацию.

С этой структурой, я могу сделать следующее:

$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 
+0

Как эта структура в конечном итоге работает для вас? –

+0

Вышеприведенный код по-прежнему используется для приложения, в котором я нуждался. Честно говоря, самой сложной частью была грамматика для Спонсора, потому что спонсирующая сторона является «спонсором», а спонсируемая сторона также является «спонсором». Это было скорее препятствием называть именования, чем кодовым. – Jeremy

Смежные вопросы