Ruby-on-rails 错误:删除表违反外键约束。密钥 ID 仍从表中引用(许多)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28996773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:06:59  来源:igfitidea点击:

ERROR: delete on table violates foreign key constraint. Key id is still referenced from table (many)

ruby-on-railspostgresqlsublimetext2better-errors-gem

提问by SUPER USER

I'm working with Rails and PostgreSQL and have a basic one-to-many relationship going on, one Auctionhas many Bids. However when I try and delete an auction (that has bids present) I get the following error:

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

ERROR: update or delete on table "auctions" violates foreign key constraint "fk_rails_43e9021cbf" on table "bids". DETAIL: Key(id)=(1) is still referenced from table "bids".

错误:更新或删除表“auctions”违反了表“bids”上的外键约束“fk_rails_43e9021cbf”。详细信息:Key(id)=(1) 仍然从表“bids”中引用。

Deleting auctions with no bids gives no error.

删除没有出价的拍卖不会出错。

The part that confuses me is that inside my Auctionmodel, I have:

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

has_many :bids, dependent: :destroy

Error Screen Shot (better_error gem)

错误屏幕截图(better_error gem)

Since I have a dependent destroy clause, why am I still getting this error?

既然我有一个从属的 destroy 子句,为什么我仍然收到这个错误?

EDIT:I've tried dropping the whole DB, then recreating/re-migrating everything - still get the same error.

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

采纳答案by SUPER USER

My issue was that i am using @auction.delete(visible in the screenshot I posted) when trying to remove a record.

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

Delete will ignore any callbacks I have in place. So even though I have a dependent destroy clause, it is not being called - hence Rails is throwing an error. If/When I changed the code to read @auction.destroy, the call-back got invoked and it solved the problem.

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

Reference: Difference between Destroy and Delete

参考: 销毁和删除的区别

回答by Mohamed Ziata

From Rails v4.2you can do this:

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

Create a migration to update the foreign keys

创建迁移以更新外键

20160321165946_update_foreign_key.rb

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

回答by John Naegle

Are you using deleteor destroyto remove the objects? I think you are using deleteand you want to use destroy

您是在使用delete还是destroy要删除对象?我认为你正在使用delete并且你想使用destroy

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

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

回答by steveklbnf

Are you by chance using the paranoiagem or something like it?

您是否偶然使用了偏执宝石或类似的东西?

If you are bidsare paranoidand auctionsare not, you may run into this error.

如果你bidsparanoidauctions不是,你可能会遇到这个错误。

This would happen because when rails executes the dependent: destroy, it would soft-deletes the bids, but they still actually exist in the DB (they just have the deleted_atcolumn set). Therefore, the foreign key constraint would fail.

之所以会发生这种情况,是因为当 rails 执行 时dependent: destroy,它会软删除出价,但它们实际上仍然存在于数据库中(它们只是deleted_at设置了列)。因此,外键约束将失败。

回答by Tony Hopkinson

Your error is from the database not rails. You need to delete the bids first in your app or change the foreign key constraint in the db to cascade the delete

您的错误来自数据库而不是 rails。您需要先在您的应用程序中删除出价或更改数据库中的外键约束以级联删除

回答by Gabriel Escodino

Marc Busqué has a very good articleabout this problem that might can help.

Marc Busqué 有一篇关于这个问题的非常好的文章可能会有所帮助。

"When ActiveRecord encounters a foreign key violation, it raises an ActiveRecord::InvalidForeignKey exception. Even if in its documentation it just says that it is raised when a record cannot be inserted or updated because it references a non-existent record, the fact is that it is also used in the case we are interested."

“当 ActiveRecord 遇到外键违规时,它会引发 ActiveRecord::InvalidForeignKey 异常。即使在其文档中只是说当记录无法插入或更新时引发,因为它引用了不存在的记录,事实是它也用于我们感兴趣的情况。”

With that and a rescue_from we can just add to ApplicationController or to a controller concern:

有了它和一个rescue_from,我们可以添加到ApplicationController或控制器关注点:

rescue_from 'ActiveRecord::InvalidForeignKey' do
  # Flash and render, render API json error... whatever
end