使用delete_all/delete删除rails活动记录违反了外键约束。
使用delete_all/delete删除rails活动记录违反了外键约束。
我在Active Record关联设置中使用了:dependent => :destroy,它按预期工作。\n然后我发现由于性能问题需要使用delete而不是destroy,所以我只是将destroy更改为delete_all/delete,具体取决于关联。\n当我尝试删除时:\n
shop.shop_snapshots.completed.last.delete
\n我收到错误消息:\n
ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR: update or delete on table "shop_snapshots" violates foreign key constraint "fk_rails_c24b24adaf" on table "inventory_items"
\n但是为什么会这样 - 我相信我在快照上有适当的设置:\n
has_many :inventory_items, :dependent => :delete_all
\n并且对于destroy,它起作用了,那么我做错了什么?\n谢谢\n/Louise
删除Rails活动记录时,使用delete_all/delete操作可能会导致外键约束冲突的问题。解决这个问题的方法是在迁移级别上进行设置。
在迁移文件中,我们可以通过设置外键约束中的on_delete选项为: cascade来解决这个问题。下面是一个示例:
create_table :childs do |t| t.references :parent, index: true, foreign_key: {on_delete: :cascade} t.string :name t.timestamps null: false end
在上述示例中,我们创建了一个名为childs的表,其中包含一个parent的外键列。通过设置foreign_key的on_delete选项为: cascade,我们可以确保当删除parent记录时,与之相关的childs记录也会被自动删除,从而避免了外键约束冲突的问题。
这样,在使用delete_all/delete操作删除Rails活动记录时,就不会出现外键约束冲突的错误了。
在Rails中使用delete_all/delete删除rails active records时,可能会违反外键约束。这个问题的出现原因是没有正确设置外键的级联选项。在Postgres中,可以在外键本身上使用CASCADE选项,它指定当删除引用的行时,相关的行也应该被自动删除。通常在创建表时会设置这个选项,但也可以通过删除然后重新添加外键约束来添加到现有表中。
以下是解决这个问题的方法。首先,需要创建一个迁移文件来移除和重新添加外键约束:
class AddCascadeToOrderItems < ActiveRecord::Migration[6.0] def up remove_foreign_key :order_items, :orders add_foreign_key :order_items, :orders, on_delete: :cascade end def down remove_foreign_key :order_items, :orders add_foreign_key :order_items, :orders end end
在这个例子中,我们移除了order_items表中的外键约束,并重新添加了一个on_delete选项为: cascade的约束。
然后,在相关的模型中,可以使用dependent选项来指定当删除父对象时如何处理关联的子对象。例如,在Store模型中:
class Store < ApplicationRecord has_many :inventory_items, dependent: :delete_all end
在这个例子中,当删除Store对象时,相关的inventory_items对象也会被删除。
需要注意的是,使用dependent: :delete_all选项只有在使用.destroy方法删除对象时才会起作用,而不是使用.delete方法。因为它是作为一个模型回调实现的。例如:
store = Store.find(1) store.destroy # 触发回调并删除所有关联的inventory_items store.delete # 不会触发回调
另外,如果需要删除关联对象的后代对象,需要正确设置外键的级联选项。使用级联选项可以确保子对象和孙子对象等都会被删除。
解决这个问题的方法是在外键中使用级联选项,并在模型中使用dependent: :delete_all选项来处理关联对象的删除。