2017-03-22 104 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,这是我写这篇文章的最新版本)。