Laravel - 如何删除具有 belongsTo 关系的模型的多态关系?

Laravel - how to delete polymorphic relations of model with belongsTo relation?

我有 4 张桌子。其中两个是单态,两个是多态

单态: 模板、模块

多态: 文档、图片

现在,templatesmodules 都有 documentsimages,每个 Template 都有很多 Modulemodules 具有设置为在删除 templates.

时级联的外键

现在,如果我删除 Template,关联的 Module 将被删除,但 Module 的关联多态关系将保留在数据库中。我没有尝试任何东西,因为我完全无能为力。

Template 被删除时,我可以做些什么来自动删除 Module 的关联?我认为这里的删除是由数据库本身处理的,Eloquent与它没有任何关系。

因为是多态关系,级联删除不能用外键处理

如果您仍希望在数据库级别处理删除,则需要编写某种类型的数据库触发器功能。

如果您想在应用程序级别处理此问题,还有几个选项。

一个选择是更新您的代码,以便在任何地方删除您的 Template,同时确保删除它的所有多态关系。

另一种选择是为 deleting 事件创建事件处理程序。每当您删除 Eloquent 模型时,deleting 事件就会由 Eloquent 触发。在此删除事件中,您可以访问多态关系并删除它们。

如果 deleting 事件方法听起来不错,那么有一个包可以为您实现所有这些,并且可以非常轻松地为您的模型进行设置:shiftonelabs/laravel-cascade-deletes。完全披露:我写了包。

使用这个包,您只需将 CascadesDeletes 特征添加到您的 Template 模型,然后添加一个包含所有关系数组的 $cascadeDeletes 属性在删除 Template 个实例时删除。

它不是全自动的,但我用 destroy() Eloquent 方法很容易处理。 https://laravel.com/docs/8.x/eloquent#deleting-an-existing-model-by-key In addition, when you will use it with Laravel Queues,它就像一个魅力...

示例:

$template = Template::find(1);

Module::destroy($template->modules);

$template->delete();

您实际上可以对两种类型的关系使用 delete 方法:

$template = Template::find(1);

$template->modules()->delete();
$template->images()->delete();

$template->delete();

这里要注意的是 $template->modules return 是一个集合实例,而 $template->modules() return 是一个 eloquent 关系,您可以在其中链接 delete() 方法。