1

所以我设置了一些模型,每个模型都可以发表评论。我已经使用 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

在这种情况下,删除项目时消息不会被删除,因为消息实际上是关系中的父级。

我对示例进行了一些简化,但还有其他模型具有消息,并且也有类似工作的附件。

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

4

2 回答 2

1

当您说“当父级被删除时,子级被删除?”,你能举个例子吗?即当一个项目被删除时,我希望它的所有消息也被删除?当您删除一条消息时会发生什么,您是否还希望删除其他任何内容(例如所有相应的 message_consumer 条目)?


更新

好的,所以has_many_polymorphs会自动删除“孤儿” message_consumer。您的问题是一条消息可能有多个消费者,因此删除一个项目可能不足以删除其所有相关消息(因为其他消费者可能依赖于这些消息。)

在这种特殊情况下,您可以在 中设置after_destroy回调MessageConsumer,以检查是否仍然存在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不再使用 a 的结论,而另一个会话可能正在MessageConsumer为该完全相同的Message. 这可以通过数据库级​​别的引用完整性(添加外键约束,这将使两个会话中的一个失败,并使您的数据库保持一致状态)或锁定(啊!)

于 2009-03-14T07:15:19.753 回答
0

您可以通过使用acts_as_commentable.

于 2009-03-15T20:31:34.300 回答