Rails: 如何在Rails中使用dependent: :destroy?

58

我有2个如下描述的模型。

class EmpGroup < ActiveRecord::Base
  belongs_to :user
  has_many :emp_group_members, dependent: :destroy
end
class EmpGroupMember < ActiveRecord::Base
  belongs_to :emp_group
  belongs_to :user
end

现在的问题是,每当我试图销毁一个组时,就会收到以下错误。

PG::ForeignKeyViolation: ERROR:  update or delete on table "emp_groups" violates foreign key constraint "fk_rails_bd68440021" on table "emp_group_members"
DETAIL:  Key (id)=(1) is still referenced from table "emp_group_members".
我错过了什么?
5个回答

59
在你的EmpGroup模型中添加级联删除功能:
class EmpGroup < ActiveRecord::Base
   has_many :emp_group_members, dependent: :delete_all
end

或者

你在调用delete方法吗?你应该调用destroy方法。使用.destroy


3
注意:在这种情况下使用destroy而不是delete非常重要,因为如果所属模型(在本例中为emp_group_member)有进一步的关联或者在任何情况下,emp_group_member的销毁方法将不会被调用,而删除将仅删除第一个子项。如果想要销毁级联到底部,请添加dependent::destroy。 @Milind的答案对于理解这一点非常有帮助。 - ARK
这个值 :delete_all 不再被允许使用了。 - Mark Swardstrom

31

:dependentbelongs_to 关联中可用的选项之一。

If you set the :dependent option to:

:destroy, when the object is destroyed, destroy will be called on its associated objects.
:delete, when the object is destroyed, all its associated objects will be deleted directly from the database without calling their destroy method.

此外,如果对象与dependent:destroy相关联,则会被销毁;如果对象与dependent:delete_all相关联,则会被删除。

在has_many关联中:

:destroy causes all the associated objects to also be destroyed
:delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not execute)

你可以尝试

 emp_member_1= @emp_group.emp_group_members.first
 ##delete associated record
 @emp_group.emp_group_members.delete(emp_member_1)

3
来自文档:“在与另一个类上的 has_many 关联相连的 belongs_to 关联中,不应指定此选项。这样做可能会导致数据库中的孤立记录。”(https://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-dependent) - BenKoshy
当然,这在文档中有说明,但它是什么意思呢? - Andrew Koster
他们警告我们不要做某些事情。但是不清楚那个“某些事情”是什么。我应该在has_many的一侧还是belongs_to的一侧放置“dependent: destroy”?这个选项的整个目的是为了避免孤立的记录,那么为什么其中一个用法会导致孤立的记录呢? - Andrew Koster
@AndrewKoster,这是一个警告 -> 这样做可能会导致您的数据库中出现孤立记录 - 这意味着您可能会删除用户,但用户有许多朋友仍然存在于数据库中,从而创建不一致性,需要在某个美好的一天进行猎捕 :). 因此,逻辑上,如果用户有许多朋友,则应该连同用户一起删除他的朋友记录,这就涉及到上述的:dependent。希望现在清楚了。 - Milind
1
我不理解的部分是为什么他们说在belongs_to方面不要使用dependent: destroy。如果它不起作用,为什么他们允许它作为一个选项呢? - Andrew Koster
因为删除 has_many 不会对 belongs_to 产生任何影响,但是删除 belongs_to 将使数据库中的 has_many 孤立无援。因此他们这样说。 - Milind

17

新语法:

class EmpGroup < ActiveRecord::Base
   has_many :emp_group_members, dependent: :destroy
end

1
当你删除一个组时,你是使用delete还是destroy。- 我之前遇到过这个错误,因为我有一个拼写错误,使用的是.delete而不是.destroy。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接