ruby-on-rails - ActiveRecord:为什么 has_many 依赖: :destroy 不起作用?
问题描述
出于某种原因,我PG::ForeignKeyViolation: ERROR
在销毁记录后得到。
在这里我有迁移
create_table :vacation_transactions do |t|
t.belongs_to :vacacion, index: true, foreign_key: true, null: true
t.references :vacacion_percibida, index: true, foreign_key: true, null: true
t.timestamps
end
在这里我有模型
class Vacacion < ApplicationRecord
has_many :vacation_transactions, dependent: :destroy
end
class VacacionPercibida < ApplicationRecord
has_many :vacation_transactions, dependent: :nullify
end
class VacationTransaction < ApplicationRecord
belongs_to :vacacion, optional: true
belongs_to :vacacion_percibida, optional: true
end
这里我有一个例子: vacacion id=348,vacacion_percibida id=950 和vacation_transaction
#<VacationTransaction:0x00007f390901cc48> {
:id => 20,
:vacacion_id => 348,
:vacacion_percibida_id => 950,
:created_at => some_date,
:updated_at => some_date
}
但是当我试图用 id=348 摧毁 vacacion 时,噩梦就发生了
Vacacion.find(348).destroy!
# PG::ForeignKeyViolation: ERROR: update or delete on table "vacacions" violates foreign key constraint "fk_rails_ae595e109b"
# on table "vacation_transactions" DETAIL: Key (id)=(348) is still referenced from table "vacation_transactions"
# if I do the next lines I get the same error
VacationTransaction.find(20).destroy! # cool
VacationTransaction.find(20) # ActiveRecord::RecordNotFound, that means the record is destroyed
Vacacion.find(348).destroy! # Same PG::ForeignKeyViolation: ERROR
我尝试在使用 id=348 销毁 vacacion 的同时调试 ActiveRecord,我发现了这个
# lib/active_record/associations/has_many_association.rb
when :destroy
load_target.each { |t| t.destroyed_by_association = reflection }
# load_target actually has the vacation_transaction record to destroy
destroy_all
# it actually destroys the vacation_transaction, in the console I can see the DELETE FROM "vacaciones_percibidas" WHERE "vacaciones_percibidas"."id" = $1
# but the error still happens
else
delete_all
end
此外,此问题仅发生在vacacion_id
FK 中,并且仅在 Vacacion 的少量记录中发生
我正在使用 ruby 2.7.4p191、Rails 6.0.4.1、ActiveRecord 6.0.4.1
那么,我错过了什么?
谢谢。
解决方案
因此,我尝试删除 FK 并再次添加它,但问题仍然存在。在最后一次尝试中,我删除并再次添加了 FK,但指定了级联参数add_foreign_key :vacation_transactions, :vacacions, on_delete: :cascade
,现在问题解决了。
我仍然不明白为什么我必须在这个特定的 FK 中指定这个,以及这个解决方案是否会在未来引发另一个问题。
推荐阅读
- javascript - Javascript - 单击侦听器未传递所有数据
- r - 如何使用两个规则有效地将数据框子集到列表列表中
- swift - 以模态方式呈现 VC 时,导航栏样式不会改变
- php - Laravel 没有使用正确的表
- android - 购买应用程序付费版本的简化方式
- sql - 使用单元格值范围内的条件运行 SQL 查询列表
- microsoft-teams - MS Teams 和 WebHook 连接器是否支持 AdaptiveCards?
- java - 如何使 GraphQL 在 Java 中进行异步/并行/并发查询?(里面的代码示例)
- javascript - React 警告:当我使用 Object.assign() 时,函数作为 React 子级无效
- plsql - 如何使用 zxjdbc 调用程序并取回 OUT 参数?