ActiveSupport :: Concern模块中的Mongoid关系

时间:2011-07-27 23:33:11

标签: ruby-on-rails-3 mongoid relationship ruby-1.9.2

我正在尝试创建一个包含与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

这是不可能的,还是我做错了什么?

1 个答案:

答案 0 :(得分:2)

我认为模块中的关联(从ScalableScale)很好,但从ScaleScalable的另一半是个问题。那是因为当您确实需要它来引用Scalable类时,目标类是从关联的名称派生的,该关联将Mongoid引导到ScalableModel模块。然后引发错误,因为Mongoid将模块视为模型类。

起初我认为你必须在可扩展包含块中定义关联的两侧,但事实证明你可以通过将关联标记为多态来修复关联的Scale侧。

还有一个问题,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