2009-01-23 56 views
1

所以我有一些模型設置可以每個都有評論。我已經使用has_many_polymorphs設置了它,但是我開始遇到一些問題,它不適合我應該如何使用它。Rails 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 

在這種情況下,消息將不會被當項目被刪除,因爲消息是真的在關係中的父刪除。

我簡化了它的一些例子,但也有其他模型有一個消息,也有附件工作類似。

設置此項的正確方法是什麼,以便在刪除父項時刪除子項?我希望沒有一百萬張桌子,但我無法想出另一種方式來做到這一點。

回答

1

當你說「讓孩子在父母被刪除時被刪除?」時,你能舉個例子嗎?即當一個項目被刪除時,我希望它的所有消息也被刪除?當你刪除一條信息時會發生什麼,你是否還想要其他的東西(例如所有相應的message_consumer條目)被刪除?


UPDATE

OK,所以has_many_polymorphs會自動刪除 「孤立」 message_consumer秒。您的問題是,消息可能有多個消費者,因此刪除項目可能不足以刪除所有相關消息(因爲其他消費者可能會依賴這些消息)。

在這種特殊情況下,您可以設置起來MessageConsumerafter_destroy回調,檢查是否還存在其他MessageConsumer映射(不是自其他)引用該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對於完全相同的Message。這可以通過數據庫級​​別的引用完整性來實施(添加外鍵約束,這會使兩次會話失敗,並保持數據庫處於一致狀態)或鎖定(唉!)

+0

是的,當一個項目被刪除時,該消息也應該被刪除。任何孤立的message_consumer條目也應該清理。 – Karl 2009-03-18 21:40:19

0

您可以通過使用acts_as_commentable來簡化這一點。

+0

消息只是一個例子,項目中還有一些其他類可以做同樣的事情。我不確定它真的適合什麼acts_as_commentable正在解決。 – Karl 2009-03-18 21:41:14