使用delete_all/delete删除rails活动记录违反了外键约束。

19 浏览
0 Comments

使用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

0
0 Comments

删除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活动记录时,就不会出现外键约束冲突的错误了。

0
0 Comments

在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选项来处理关联对象的删除。

0