我遇到了Rails 3.2关联和PostgreSQL外键之间的细微差别,我想确保我理解管理它的最佳方式。如何管理Rails关联和数据库外键约束之间的区别?
假设一个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);"
然后我得到一个相当恶劣的中止,因为关键是仍在使用:
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_many
和belongs_to
跟踪哪些领域持有外国键。删除“父”记录时,不会验证子记录不会成为孤儿。带有外键约束的PostgreSQL要求在删除父项之前,所有子项均与父项“取消关联”。只要外键可以为空,这可以通过在删除父项之前将子项的外键设置为null来完成。
在我的情况,我想向允许孤儿。我最好忘记数据库限制,还是在保留它和删除父母时删除记录的链接方面有价值?
感谢您的提示。我会尽力记住,如果/当我回到这个项目。 –