【问题标题】:Laravel, delete related data from DatabaseLaravel,从数据库中删除相关数据
【发布时间】:2020-01-06 14:06:10
【问题描述】:

我有 3 个应该相关的表,但它们不相关:

'tables' <-- this is a normal Laravel table with created_at and updated_at
--------
id|name
--------
5 |people


'filters' <-- this is a normal Laravel table with created_at and updated_at
-------------
id | table_id
-------------
10 | 5


'filter_users' <- this is a pivot table
-------------
user_id|filter_id
-------------
 66    | 10

我需要当有人从“表”中删除一行时,也从“过滤器”和“过滤器用户”中删除

这 3 个值:

table.id = 5 -> filters.id = 10 -> filter_users.filter_id = 10

使用DELETE CASCADE 在“filters”和“filter_users”表上设置FK 就足够了:

ALTER TABLE public.filters ADD CONSTRAINT filters_fk FOREIGN KEY (table_id) REFERENCES public."tables"(id) ON DELETE CASCADE;

或者我应该对模型使用一些限制吗?

【问题讨论】:

  • 如果这是belongsToMany()/many-to-many 关系,如果您删除tables 中的某些内容,您将不想删除filters 中的任何内容,因为它可能与tables 中的另一条记录相关。删除中间数据就像$table-&gt;filters()-&gt;detach(); 一样简单(假设您定义了正确的关系)
  • 我尝试了关于 CASCADE 的内容,但由于带有 id 的旧数据不再存在于一个表或另一个表中,因此我遇到了很多错误。你说的听起来是对的,但是这里的代码是关于删除、插入等的自定义方法的混乱,里面有原始的 sql。我必须在 Table 模型中放入更多原始 sql 以删除我需要的“级联”:(
  • 您可以简单地为 filter 和 filter_users 表添加级联

标签: sql laravel postgresql


【解决方案1】:

在大多数情况下,使用 ON DELETE CASCADE 的数据库解决方案已经足够好了,直到您在模型上使用 SoftDelete

在这种情况下,ON DELETE CASCADE 不会被触发,因为它只是一个更新。正如@Himanshu 所说,您可能仍然可以使用trigger,但您需要设置两个触发器(更新和删除)。

最后一个解决方案,而不是最好的解决方案,是通过代码来实现,方法是在模型中重载 delete() 方法。

【讨论】:

    【解决方案2】:

    您可以在没有约束的情况下使用触发器

      Create trigger sample
      After DELETE on
      Table for Each Row
    
      DELETE FROM FILTERS F JOIN
      FILTER_USERS FU ON 
      New.ID=F.TABLEID AND
      F.ID=FU.FILTERID
      END
    

    【讨论】:

      猜你喜欢
      • 2017-11-29
      • 2021-06-08
      • 2019-06-08
      • 2019-09-16
      • 1970-01-01
      • 2021-10-22
      • 2015-10-13
      • 2023-02-26
      • 1970-01-01
      相关资源
      最近更新 更多