2015-04-15 60 views
1

我試圖用一箇中介表來表示下列要求兩個不同的用戶表(員工&非僱員)之間的關係,贊助關係多態:與多個關聯

  • 申辦者可或者是員工或非員工。
  • 員工/非員工只能屬於一個贊助商。
  • 員工可以有很多贊助商。

我注意到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不支持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