错误: 在表中删除违反了外键约束。键id仍然被表(many)引用。
错误: 在表中删除违反了外键约束。键id仍然被表(many)引用。
我正在使用Rails和PostgreSQL,有一个基本的一对多关系,一个拍卖(Auction)有多个竞标(Bid)。然而,当我尝试删除一个有竞标的拍卖时,出现以下错误:\n
\nERROR: 在表“bids”上,表“auctions”的更新或删除违反了外键约束“fk_rails_43e9021cbf”。详细信息:键(id)=(1)仍然在表“bids”中被引用。\n
\n删除没有竞标的拍卖不会出错。\n让我困惑的是,在我的拍卖模型中,我有:\nhas_many :bids, dependent: :destroy
\n\n既然我有一个dependent destroy子句,为什么还会出现这个错误?\n编辑:我尝试删除整个数据库,然后重新创建/重新迁移所有内容,仍然出现相同的错误。
我遇到的问题是在尝试删除记录时使用了.delete
(在我发布的截图中可见)。
Delete将忽略我已经设置好的任何回调。因此,即使我有一个依赖于destroy子句,它也不会被调用,因此Rails会抛出错误。当我将代码改为.destroy
时,回调被调用并解决了问题。
参考链接:
非常好的发现!这正是我的问题所在!
在删除数据库中的对象时,是否使用了delete
或destroy
方法?根据问题描述,猜测你可能使用了delete
方法,而应该使用destroy
方法。
感谢!将delete
替换为destroy
解决了问题!
在Rails 4.2版本中,我们可以通过创建一个migration来更新外键。具体操作如下:
1. 创建一个migration文件,命名为`20160321165946_update_foreign_key.rb`。
2. 在该migration文件中,首先移除旧的外键(`remove_foreign_key :posts, :users`)。
3. 然后添加新的外键(`add_foreign_key :posts, :users, on_delete: :cascade`)。
对于初始的引用创建migration,也可以采用类似的方法。例如:
class CreateJobQueries < ActiveRecord::Migration[5.0] def change add_reference :job_queries, :user, foreign_key: true, on_delete: :cascade end end
从Rails 5.1.4的角度来看,我觉得`foreign_key`是一个数据库级别的设置,而`dependent: :delete_all`是一个模型级别的设置。如果我们在数据库中设置了外键(查看`schema.rb`),那么仅使用`dependent: :delete_all`是不够的,我们还需要在数据库级别上加上`on_delete: :cascade`。我在这篇文章中找到了一些有用的信息:spin.atomicobject.com/2016/10/04/…。
这个方法很好,对我来说解决了问题。但是,为什么我们告诉Rails使用`dependent: :destroy`时,还要通过数据库来清理呢?在其他代码库中,我从未见过这种情况,但是在我的当前代码库中,我不得不大量使用这种方法。