In my app, we have to create models on the runtime, and embed them within the current model. These created models may also in turn embed models. To get some common ground for these embeddable models, I've created a module that can be included into them.
For example:
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
So, the fields of MModel
and its embedded documents are made with help of the Context
model.
The problem here is that, while non-nested fields are made, and can be validated on the fly, nested (embedded) models seem to have a problem: they are not initialized when a new MModel
is made, and data is passed to it. The first level works, any level below it simply doesn't.
Any hints on this?