Rails has_many_polymorphs反向?

时间:2009-01-23 20:49:57

标签: ruby-on-rails ruby has-many-polymorphs

所以我设置了一些模型,每个模型都有评论。我使用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,并且还有类似的附件。

设置此项的正确方法是什么,以便在删除父项时删除子项?我希望没有一百万张桌子,但我无法想出另一种方法来做到这一点。

2 个答案:

答案 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来简化此操作。