- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有几个表具有与之关联的外键约束,每个表都以分层方式引用另一个表,如下所述。
当我试图销毁一家至少有 1 个项目、至少有 1 个任务、至少有 1 个任务时间的公司时...
irb(main):014:0> Company.first.destroy
我得到以下输出和错误。我现在的印象是简单地拥有 dependent: :delete_all
不处理外键约束,这是真的吗?如果是这样,我该如何处理这种情况?我知道 before_destroy
回调,在这种情况下我必须使用它吗?如果是这样,我如何暂时禁用外键约束以破坏所有关联的行?更令人困惑的是,我有一个旧的 Rails 项目,它设置了相同的表/模型,只是它是一个 model_a has_many model_bs, dependent: delete_all
与外键约束的关系,我可以ModelB.destroy_all
它有效,所以我不明白。我还读过在表上设置级联删除的帖子,还有一些帖子说如果你自己在代码中处理它就不需要这样做;如果解决方案不太复杂,我想在我的代码中处理这个问题。
Company Load (0.4ms) SELECT "companies".* FROM "companies" ORDER BY
"companies"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.2ms) BEGIN
SQL (0.9ms) DELETE FROM "projects"
WHERE "projects"."company_id" = $1 [["company_id", 3]]
(0.1ms) ROLLBACK
Traceback (most recent call last):
1: from (irb):13
ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR: update or delete on table "projects" violates foreign key constraint "fk_rails_02e851e3b7" on table "tasks"
DETAIL: Key (id)=(4) is still referenced from table "tasks".
: DELETE FROM "projects" WHERE "projects"."company_id" = $1)
架构
# /db/schema.rb
create_table "companies", force: :cascade do |t|
...
end
create_table "projects", force: :cascade do |t|
...
end
create_table "tasks", force: :cascade do |t|
...
end
create_table "task_times", force: :cascade do |t|
...
end
...
add_foreign_key "projects", "companies"
add_foreign_key "tasks", "projects"
add_foreign_key "task_times", "tasks"
模型
# /models/company.rb
class Company < ApplicationRecord
has_many :projects, dependent: :delete_all
...
end
# /models/project.rb
class Project < ApplicationRecord
has_many :tasks, dependent: :delete_all
...
end
# /models/task.rb
class Task < ApplicationRecord
has_many :task_times, dependent: :delete_all
...
end
# /models/task_time.rb
class TaskTime < ApplicationRecord
...
end
最佳答案
来自fine manual :
has_many(name, scope = nil, options = {}, &extension)
[...]
:dependent
Controls what happens to the associated objects when their owner is destroyed. Note that these are implemented as callbacks, and Rails executes callbacks in order. Therefore, other similar callbacks may affect the:dependent
behavior, and the:dependent
behavior may affect other callbacks.
:destroy
causes all the associated objects to also be destroyed.:delete_all
causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).- [...]
所以 :delete_all
确实处理了外键,但是,由于没有调用回调,它只深入一层。所以在 Company
中:
has_many :projects, dependent: :delete_all
表示对公司调用#destroy
将直接从数据库中删除关联的项目
。但是那不会看到这个:
has_many :tasks, dependent: :delete_all
您在 Project
中拥有的内容,并且您最终尝试删除仍在 tasks
中引用的项目,如错误消息所示。
您可以将所有关联切换为dependent::destroy
,这将在销毁它们之前将所有内容从数据库中拉出并调用回调(这将从数据库中加载更多内容只是为了销毁它们,这将从数据库中加载更多的东西......)。最终结果将是大量的数据库事件,但所有外键都将得到正确遵循。
或者,您可以通过指定 on delete cascade
on the foreign key constraints 将逻辑放在它通常所属的数据库中。 :
CASCADE specifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well
您的 add_foreign_key
调用如下所示:
add_foreign_key "projects", "companies", on_delete: :cascade
add_foreign_key "tasks", "projects", on_delete: :cascade
add_foreign_key "task_times", "tasks", on_delete: :cascade
在这种情况下。您可能希望在模型中保留 dependent: :delete_all
作为正在发生的事情的提醒,或者您可以给自己留下评论。
关于ruby-on-rails - PG::ForeignKeyViolation: 错误:更新或删除表 "xxx"违反了外键约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48739646/
我已将我的 Rails 应用程序从 SQLite 更新到 Postgres,当我尝试添加新产品库存时出现以下错误: ActiveRecord::InvalidForeignKey: PG::Forei
我有几个表具有与之关联的外键约束,每个表都以分层方式引用另一个表,如下所述。 当我试图销毁一家至少有 1 个项目、至少有 1 个任务、至少有 1 个任务时间的公司时... irb(main):014:
我的模型: class Foo < ActiveRecord::Base has_many :bars, inverse_of: :foo accepts_nested_attributes_
我有一个Book 模型和一个User 模型。我正在尝试在 books 表中创建一个名为 author_id 的新列,它实际上是 users 表的外键。 我关注了this article by Josh
我有 2 个模型,Bidding 和 BiddingItem。 class Bidding < ActiveRecord::Base has_many :bidding_items, depen
我正在使用 Active Admin,因此 adminuser 可以创建/删除类别、标签和产品。 我可以创建 Labels、Categories 和 Products 而没有任何问题,但是当我想删除标
我遇到了 Minitest 和关联 ActiveRecord 模型 (Rails.4.2.3) 的问题。 这是两个模型: # vanguard_fund.rb class VanguardFund <
我最近将 has_and_belongs_to_many (HABTM) 关联切换为 has_many :through 关联,现在由于违反外键约束,我有很多失败的测试。这是一个示例测试失败消息: D
所以我又发了一篇关于这个 issue 的帖子,我想我会进一步分解它,看看 StackOverflow 的好人是否能弄清楚发生了什么,因为我做不到。因此,我使用 setUpTestData 在下面生成了
我是一名优秀的程序员,十分优秀!