2011-07-27 8 views
2

Mongoidと多相関係を含むモジュールを作成しようとしています。簡単な例:私はScalableModel.createような何かを実行しようとすると、ActiveSupport :: Concernモジュール内の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 

は、しかし、私は次のエラーを取得する:

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

は、これは不可能ですか、私が何か間違ったことをやっていますか?

答えて

2

私は(ScalableからScaleに)モジュール内の関連付けが細かいですが、ScaleからScalableとは反対の半分が問題だと思います。ターゲットクラスは、クラスを参照するために本当に必要なときに、MongoidをScalableモジュールに導いている関連の名前から派生しているからです。 Mongoidはモジュールをモデルクラスとして扱っているため、エラーが発生します。

最初は、スケーラブルインクルードブロックでアソシエーションの両側を定義する必要があると思っていましたが、アソシエーションのスケール側をポリモーフィックとして固定することができます。

もう1つの問題があります。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

非常に、スティーブ、それは完璧に働いてくれてありがとうございます。実際にコールバックを保存する前に、 ':autosave => true'を追加し、' self.scales.create'をコールバックの 'self.scales.build'に変更することで、コールバックを保存することができました。 – geetarista

関連する問題