我对类别有多态关系,它们可以属于客户端或模板。
我尝试将模板中的类别分配给客户端。但它覆盖了我的模板类别。
类别模型
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);
}
但是它覆盖了我的类别表中的两个类别。因此,将它们保存在客户端上,但将其从模板中删除。
答案 0 :(得分:0)
这是有道理的。您的Category
模型表有两列,一列是附加到的模型类型,另一列是id(可能是categorisable_type
(类似于“App \ Models”) \ Template“)和categorisable_id
(类似于”4“))。
因此,每次重新分配已存在的类别时,它会将这两列从模型模型重写为客户端模型(例如,它会更改为“App \ Models \ Client”和“6”)。 / p>
这里有几个选项:
1)您的关系类型实际上并不理想。你可以在这里使用简单的one2many。创建几个cateogries,然后在Template和Client模型上有一个category_id。这样,您就可以在模板和客户端上使用相同的类别。
2)如果您需要为每个模板或客户端附加多个类别,请使用many2many关系。其余类似于选项1,你将只有两个表,比如category_client
和category_template
,假设你遵循Laravel命名约定,但你真的可以使用任何东西,你只需要在关系方法中指定它。
3)你也可以使用many2many多态关系。您最终会得到clients
,templates
,categories
和categorisable
表格。 categories
表只保留类别,categorisable
将具有关系定义,类似于选项2.
4)如果你坚持在这里使用one2many多态关系(建议:不要),你可以为你指定的每个客户端克隆每个模板,但这没有任何意义,你实际上不会有与您的Template
或Client
相关联的同一类别,只是原始版本的克隆,因此您无法从{{{{{}}反向访问多个templates
或client
1}},因为它们都属于不同的类别。
方法1和2实际上以正确的顺序颠倒整个关系,因为您当前的逻辑是反转的,并且如上所述,并不理想。
此处有更多信息 - https://laravel.com/docs/5.4/eloquent-relationships(对于Laravel 5.4,这是我写这篇文章时的最新版本。)