繁体   English   中英

Laravel多态关系在保存时被覆盖

[英]Laravel Polymorphic relation overwrites on save

我在类别上有一个多态关系,它们可以属于客户或模板。

我正在尝试将模板中的类别分配给客户端。 但这覆盖了我的模板类别。

分类模型

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);
}

但是,这将覆盖我的类别表中的两个类别。 因此,将它们保存在客户端上,但是将其从模板中删除。

这是有道理的。 您的Category模型表有两列,一列是它所连接的模型的类型,另一列是id(可能是categorisable_type (可能类似于“ App \\ Models \\ Template”之categorisable_id东西))和categorisable_id (就像“ 4”))。

因此,每次您重新分配已经存在的类别时,它将这两列从Template模型重写为Client模型(例如,它更改为“ App \\ Models \\ Client”和“ 6”之类)。

您在这里有几种选择:

1)您的关系类型实际上并不理想。 您可以在此处使用简单的一个。 创建几个类别,然后在您的模板和客户端模型上使用category_id。 这样,您就可以在模板和客户端上使用相同的类别。

2)如果您需要将多个类别附加到每个模板或客户端,请使用many2many关系。 其余部分与选项1类似,假设您遵循Laravel命名约定,则只剩下两个表,例如category_clientcategory_template ,但您实际上可以使用任何表,只需在关系方法中指定它即可。

3)您也可以使用many2many多态关系。 您最终将获得clientstemplatescategories和可categorisable表。 categories表仅包含类别,可categorisable将具有关系定义,类似于选项2。

4)如果您在此处坚持使用one2many多态关系(建议:不要),则可以为要分配给它的每个客户端克隆每个模板,但这意义非零,实际上您将没有附加相同的类别到您的TemplateClient ,只是原始Template的克隆,因此您将无法从Category反向访问多个templatesclient ,因为它们都属于不同的类别。

方法1和2实际上以正确的顺序反转了整个关系,因为您当前的逻辑是相反的,并且如上所述,这并不理想。

更多资讯- https://laravel.com/docs/5.4/eloquent-relationships (对于Laravel 5.4,这是在我写这篇文章时的最新版本)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM