0

在我的应用程序中,我们必须在运行时创建模型,并将它们嵌入到当前模型中。这些创建的模型也可以反过来嵌入模型。为了获得这些可嵌入模型的共同点,我创建了一个可以包含在其中的模块。

例如:

module CommonMethods
  def make_self(context)
    if context['nested']
      inner_klass_name = context['name'].classify
      inner_klass = Object.const_set(inner_klass_name, Class.new)
      inner_klass.class_eval <<-ENDSRC
        include Mongoid::Document
        include CommonMethods

        embedded_in :#{@mclass_name.underscore}, :inverse_class_name => "#{@mclass_name}"

        after_initialize :start_make_self

        def start_make_self
          @mclass_name = "#{inner_klass_name}"
          make_self(#{context['nested_context']})
        end
      ENDSRC

      self.class_eval <<-ENDSRC
        embeds_one :#{context['name']}, :inverse_class_name => "#{inner_klass_name}"
      ENDSRC
    else
      self.class_eval <<-ENDSRC
        field :#{context['name']}, :type => String
      ENDSRC
    end
  end
end

class MModel
  include Mongoid::Document
  include CommonMethods

  field :context_id, :type => String
  after_initialize :start_make_self

  def start_make_self
    context = Context.where(:uid => self.context_id)
    @mclass_name = "MModel"
    make_self(context.attributes)
  end
end

因此,它的字段MModel及其嵌入文档是在Context模型的帮助下制作的。

这里的问题是,虽然生成了非嵌套字段,并且可以动态验证,但嵌套(嵌入式)模型似乎存在问题:在生成新字段时它们没有被初始化MModel,并且数据被传递给它。第一级有效,低于它的任何级别都不起作用。

对此有任何提示吗?

4

1 回答 1

0

我通过覆盖类的构造函数部分解决了这个问题。

class MModel
  include Mongoid::Document
  include CommonMethods

  field :context_id, :type => String

  def initialize(attrs=nil)
    context = Context.where(:uid => attrs[:context_id])
    @mclass_name = "MModel"
    make_self(context.attributes)
    super
  end
end

对于 inner_klass 也是如此。剩下的唯一问题是,虽然关系和验证工作(embeds_one等),但运行时字段声明似乎不起作用。例如,使用类型声明为 an 的字段Array不受支持。我通过提供相同的自定义验证暂时解决了这个问题。

于 2012-08-02T05:38:33.567 回答