Pet*_*des 13 cascade ruby-on-rails foreign-keys dependent-destroy
我正在尝试决定如何最好地设置(如果有的话)我的rails应用程序的外键约束.我有一个模型Response,belongs_to一个Prompt.我想使用:dependent => :destroy每个Response属于删除的每个调用destroy Prompt,我试图决定我应该在我的外键上放置什么删除约束.
简而言之,我想要了解如何最好地利用依赖对象的destroy方法和外键约束,以确保cruft不会累积并反映存储数据的逻辑结构.几个早期的问题,比如我应该使用ON DELETE CASCADE,:dependent =>:destroy,还是两者都有?和Rails:删除cascade vs dependent destroy询问哪个更好但是他们并没有真正说明两个选择如何相互作用以及它们被触发的顺序或者看起来模糊不清.
正如我所看到的那样,考虑因素似乎分为几个方面:
:dependent => :destroy在从数据库中删除父对象之前,调用是否首先在依赖对象上进行销毁,因此即使我使用级联删除,仍会在这些对象上调用destroy?是否:dependent => :destroy从数据库中移除父项之前(或在事务中)从数据库中删除依赖对象?换句话说,如果我将cascade设置为nullify,数据库最终会在删除子对象之前浪费地取消它们的引用吗?
是否由于原始销毁和链接:dependent => :destroy选项包含在事务中而发出删除,或者遗憾的是,如果我没有设置级联删除,则会在数据库中暂时崩溃?
:dependent => :destroy如果我使用restrict作为外键on_delete选项,最后将确保从数据库中删除父对象?随着dependent: :destroy在轨交易第一销毁所有依赖关系,然后才删除记录本身。
可能存在竞争条件:如果在 rails 读取集合进行销毁后添加了依赖记录,但尚未删除父记录 - 它可能会被遗留下来。让我们在下面称这些为“竞争条件记录”。
是的,您可以使用dependent: :destroyand on delete cascade,这样可以在没有回调的情况下删除一些子项(竞争条件的子项)。如果回调是强制性的 -on delete restrict加上一些锁定和明确的子项删除可能会更好。这有点像validates :some_field, uniqueness: true唯一索引做后盾更好,只有数据库本身才能保证数据的一致性。
由于最后删除了父级,on delete nullify因此不会妨碍(您将获得无效的竞争条件记录)
有事务包装所有删除,只能留下竞争条件记录
on delete restrictoverdependent: :destroy只会触发竞争条件记录(并回滚整个事务),但如果没有竞争条件 - rails 会很乐意删除所有内容。