2011-07-27 171 views
2

我正嘗試創建一個包含與Mongoid的多態關係的模塊。簡單的例子:ActiveSupport中的Mongoid關係::關注模塊

module Scalable 
    extend ActiveSupport::Concern 

    included do 
    references_many :scales, :as => :scalable 

    before_save :add_scale 
    end 

    module InstanceMethods 
    def add_scale 
     self.scales.create 
    end 
    end 
end 

class Scale 
    include Mongoid::Document 

    referenced_in :scalable, :index => true 
end 

class ScalableModel 
    include Mongoid::Document 
    include Scalable 
end 

然而,當我試圖像ScalableModel.create運行的東西,我得到以下錯誤:

NoMethodError Exception: undefined method `relations' for Scalable:Module 

這是不可能的,還是我做錯了什麼?

回答

2

我認爲模塊(從ScalableScale)在協會是好的,但相反的一半ScaleScalable是一個問題。這是因爲目標班級是根據將Mongoid引導至Scalable模塊的關聯名稱派生出來的,當您真的需要它參考ScalableModel類時。然後提出錯誤,因爲Mongoid將模塊視爲模型類。

起初我以爲你必須在可擴展的包含塊中定義關聯的兩側,但事實證明,你可以通過標記爲多態來修復關聯的縮放側。

還有另外一個問題,self.scale.create引發異常,因爲直到保存父對象後才能創建新的子對象。爲了解決這個問題,我只使用了after_save。這是我想出來的:

module Scalable 
    extend ActiveSupport::Concern 

    included do 
    references_many :scales, :as => :scalable 
    after_save :add_scale      # changed from before_save 
    end 

    module InstanceMethods 
    def add_scale 
     self.scales.create 
    end 
    end 
end 

class Scale 
    include Mongoid::Document 
    referenced_in :scalable_model, :index => true, :polymorphic => true 
end 

class ScalableModel1 
    include Mongoid::Document 
    include Scalable 
end 

class ScalableModel2 
    include Mongoid::Document 
    include Scalable 
end 

s1 = ScalableModel1.create 
s2 = ScalableModel2.create 
+0

非常感謝Steve,這很好地工作。通過添加':autosave => true'並將'self.scales.create'更改爲'self.scales.build'在回調中,我實際上能夠保留回調。 – geetarista