2017-03-22 98 views
2

我對類別有多態關係,它們可以屬於客戶端或模板。Laravel多態關係覆蓋保存

我正在嘗試從模板分配給客戶端。但它覆蓋了我的模板類別。

分類模式

class Category extends Model 
{ 

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

客戶端模式

class Client extends Model 
{ 
    public function categories() 
    { 
     return $this->morphMany(Category::class, 'categorisable'); 
    } 
} 

模板模型

class Template extends Model 
{ 
    public function categories() 
    { 
     return $this->morphMany(Category::class, 'categorisable'); 
    } 
} 

這是我想在分類從模板複製到客戶端

$template = Template::find($request->get('template_id')); 
$client = Client::find($request->get('client_id')); 

// For this template, get all categories 
foreach($template->categories as $category) { 
    $client->categories()->save($category); 
} 

但後來它覆蓋2個類別在我的類別表的代碼。因此將它們保存在客戶端上,但將它們從模板中刪除。

任何幫助將不勝感激! 謝謝。

回答

0

這是有道理的。 Category模型的表格有兩列,一列是它所連接模型的類型,另一列是用於標識(可能是categorisable_type(它可能類似於「App \ Models \ Template」)和categorisable_id(其中會像「4」))。

因此,每次您重新分配已存在的類別時,都會將這兩列從模板模型重寫爲客戶端模型(因此它會更改爲「App \ Models \ Client」和「6」之類的內容)。

您有幾種選擇在這裏:

1)你的關係類型實際上是不理想的。你可以在這裏使用簡單的one2many。創建幾個cateogries,然後在模板和客戶端模型上有一個category_id。這樣您就可以在模板和客戶端上使用相同的類別。

2)如果您需要有幾類附加到每個模板或客戶端,使用many2many關係。剩下的就是類似的選項1,你只需要兩個表,像category_clientcategory_template,假設您按照Laravel命名約定,但你真的可以用任何東西,你只需要在關係的方法來指定。

3)您也可以使用多態many2many關係。您將與clientstemplatescategoriescategorisable表結束。 categories表將牽住類別,categorisable將有關係的定義,類似於選項2。如果你堅持在這裏使用one2many多態關係(建議:不要),你可以克隆每個你分配給它的客戶端的每個模板,但這是毫無意義的,你實際上不會有與您的TemplateClient相同的類別只是原件的副本,因此您將無法反向訪問來自Category的多個templatesclient,因爲它們都屬於不同的類別。

方法1和2實際上是以正確的順序顛倒整個關係,因爲你的當前邏輯是反轉的,並且如前所述,並不理想。

更多的信息在這裏 - https://laravel.com/docs/5.4/eloquent-relationships(對於Laravel 5.4,這是我寫這篇文章的最新版本)。