所以我设置了一些模型,每个模型都有评论。我使用has_many_polymorphs进行了设置,但是我开始遇到一些问题,我认为它应该不起作用。
例如:
class Project < ActiveRecord::Base
end
class Message < ActiveRecord::Base
has_many_polymorphs :consumers,
:from => [:projects, :messages],
:through => :message_consumers,
:as => :comment # Self-referential associations have to rename the non-polymorphic key
end
class MessageConsumer < ActiveRecord::Base
# Self-referential associations have to rename the non-polymorphic key
belongs_to :comment, :foreign_key => 'comment_id', :class_name => 'Message'
belongs_to :consumer, :polymorphic => true
end
在这种情况下,删除项目时不会删除消息,因为消息实际上是关系中的父级。
我为示例简化了一点,但是还有其他模型有一个Message,并且还有类似的附件。
设置此项的正确方法是什么,以便在删除父项时删除子项?我希望没有一百万张桌子,但我无法想出另一种方法来做到这一点。
答案 0 :(得分:1)
当你说“当父母被删除时孩子被移除了吗?”,你能举个例子吗?即删除项目时我想删除所有邮件吗?删除邮件时会发生什么,是否还要删除其他任何内容(例如所有相应的message_consumer条目)?
<强>更新强>
好的,has_many_polymorphs
会自动删除“孤儿”message_consumer
。您的问题是消息可能有多个消费者,因此删除项目可能不足以删除其所有相关消息(因为其他消费者可能依赖于这些消息。)
在这种特殊情况下,您可以在after_destroy
中设置MessageConsumer
回调,以检查是否还存在引用{{1}的其他MessageConsumer
映射(除了self之外)如果不存在,也删除该消息,例如:
Message
所有这一切都发生在一个事务中,所以要么所有删除都成功,要么都没有成功。
您应该只知道潜在的竞争条件,即一个会话得出的结论是class MessageConsumer < ActiveRecord::Base
...
after_destroy :delete_orphaned_messages
def delete_orphaned_messages
if MessageConsumer.find(:first, :conditions => [ 'comment_id = ?', self.comment_id] ).empty?
self.comment.delete
end
end
end
不再使用,而另一个会议可能正在创建新的Message
完全相同MessageConsumer
。这可以通过数据库级别的引用完整性来强制执行(添加外键约束,这将使两个会话失败,并使数据库保持一致状态)或锁定(呃!)
答案 1 :(得分:0)
您可以使用acts_as_commentable
来简化此操作。