错误:表上的删除违反了外键约束.密钥id仍然从表中引用(很多)

SUP*_*SER 40 postgresql ruby-on-rails sublimetext2 better-errors-gem

我正在使用Rails和PostgreSQL并且有一个基本的一对多关系,一个Auction有很多Bids.但是,当我尝试删除拍卖(有出价)时,我收到以下错误:

错误:表"update"上的更新或删除违反了表"bid"上的外键约束"fk_rails_43e9021cbf".详细信息:密钥(id)=(1)仍然从表"出价"中引用.

删除没有出价的拍卖会没有错误.

令我困惑的部分是在我的Auction模型中,我有:

has_many :bids, dependent: :destroy
Run Code Online (Sandbox Code Playgroud)

错误屏幕截图(better_error gem)

由于我有一个依赖的destroy子句,为什么我仍然会收到此错误?

编辑:我已经尝试删除整个数据库,然后重新创建/重新迁移所有内容 - 仍然得到相同的错误.

Moh*_*ata 34

Rails v4.2开始,你可以这样做:

创建迁移以更新外键

20160321165946_update_foreign_key.rb

class UpdateForeignKey < ActiveRecord::Migration
  def change
    # remove the old foreign_key
    remove_foreign_key :posts, :users

    # add the new foreign_key
    add_foreign_key :posts, :users, on_delete: :cascade
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我修正了这个错字. (2认同)
  • (从 Rails 5.1.4 的角度来看)我觉得foreign_key 是数据库级别的设置,而dependent: :delete_all 是模型级别的设置。如果我们在数据库中设置了foreign_key(检查您的schema.rb),dependent::delete_all 是不够的,我们也需要在数据库级别的on_delete::cascade。我发现这篇文章很有帮助:https://spin.atomicobject.com/2016/10/04/rails-active-record-postgres-optimizing-deletions/。 (2认同)

Joh*_*gle 17

您使用deletedestroy删除对象?我认为你正在使用delete,你想使用destroy

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Delete+or+destroy-3F

  • 谢谢 !切换到销毁而不是删除修复了问题! (2认同)

SUP*_*SER 13

我的问题是我在尝试删除记录时正在使用@ auction.delete(在我发布的屏幕截图中可见).

删除将忽略我所拥有的任何回调.所以即使我有一个依赖的destroy子句,它也没有被调用 - 因此Rails会抛出一个错误.如果/当我将代码更改为@ auction.destroy时,调用了回调并解决了问题.

参考: Destroy和Delete之间的区别


小智 9

你偶然使用偏执狂宝石或类似的东西吗?

如果您是bids,paranoid而且auctions不是,您可能会遇到此错误.

这会发生,因为当rails执行时dependent: destroy,它会软删除出价,但它们实际上仍存在于DB中(它们只是deleted_at设置了列).因此,外键约束将失败.