ruby-on-rails-3 - 如何管理 Rails 关联和数据库外键约束之间的差异?

标签 ruby-on-rails-3 postgresql

我遇到了 Rails 3.2 关联和 PostgreSQL 外键之间的细微差别,我想确保我了解管理它的最佳方法。

假设一个 Message 类跟踪它正在回复的消息。删除“来自”消息不应删除链中的其余消息,因此没有 :dependent => :destroy 子句。

class Message < ActiveRecord::Base
  # from_message_id self-reference
  has_many   :from_messages, :foreign_key => "from_message_id", 
             :class_name => "Message", :inverse_of => :from_message
  belongs_to :from_message, 
             :class_name => "Message", :inverse_of => :from_messages

  attr_accessible :from_message_id, subject, body
end

现在,如果我创建两个链接的消息,并删除第一个,Rails 只会报告它不存在:

m1 = Message.create
m2 = Message.new
m2.from_message = m1
m2.save
m1.destroy
m2.from_message
=> nil

但是,如果我还从迁移中向数据库添加实际的外键约束:

execute "ALTER TABLE messages ADD CONSTRAINT messages_from_message_fk 
         FOREIGN KEY (from_message_id)  REFERENCES messages(id);"

然后我得到一个相当讨厌的中止,因为 key 仍在使用中:

m1 = Message.create
m2 = Message.new
m2.from_message = m1
m2.save
m1.destroy
=> ActiveRecord::InvalidForeignKey: PG::Error: ERROR:  update or delete on table 
"messages" violates foreign key constraint "messages_from_message_fk" on 
table "messages"
DETAIL:  Key (id)=(2) is still referenced from table "messages".

这些结论正确吗?

  • Rails 仅使用 has_manybelongs_to 来跟踪哪些字段拥有哪些外键。删除“父”记录时,不会验证子记录不会被孤立。

  • 具有外键约束的 PostgreSQL 要求在删除父项之前,所有子项都与父项“断开链接”。只要外键可以为空,就可以通过在删除父级之前将子级的外键设置为空来实现这一点。

就我而言,我希望允许孤儿。我最好只是忘记数据库约束,还是保留它并在删除其父项时取消链接记录有一些值(value)?

最佳答案

In my case, I want to allow orphans. Am I better off just forgetting the database constraint, or is there some value in retaining it and unlinking records as their parents are deleted?

在 PostgreSQL 中,通过删除外键约束来更改表,然后使用 ON DELETE SET NULL 重新添加它;在这种情况下,删除将级联到将外键设置为空,从而允许孤儿。

关于ruby-on-rails-3 - 如何管理 Rails 关联和数据库外键约束之间的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10989691/

相关文章:

ruby-on-rails-3 - Rails : update_column works, 但不是 update_attributes

ruby-on-rails - 使用包含图像的 Prawto 生成 PDF

ruby-on-rails - Rails 3.2 防止使用错误保存对象

ruby-on-rails - Rails 将包含日期时间的字符串转换为日期

sql - 不区分大小写的重复 SQL

ruby-on-rails - 如何在 Rails 4 中仅从数据库中提取文本字段的一部分

ruby-on-rails - rails 3 : How can I add a complex row to a table using UJS?

sql - 每个后代叶子在深度 d 处的节点名称

ruby-on-rails - Rails,按 created_at day 分组的用户数 - PostgreSQL

sql - PostgreSQL - 相关子查询失败?