Rails 3 using MongoDB via mongoid adapter - is there any way to share attribute specifications without using Single-Table Inheritance?
mongodb, mongoid, ruby-on-rails-3, sti
Solution
You can define the common attributes in a module and include that.
require 'mongoid'
module DefaultAttrs
def self.included(klass)
klass.instance_eval do
field :uuid, :type => String
end
end
end
class Foo
include Mongoid::Document
include DefaultAttrs
field :a, :type => String
end
class Bar
include Mongoid::Document
include DefaultAttrs
field :b, :type => String
end
Problem
Probably a confusing title, but not sure how else to put it. Example should make it clearer. I have many different models that share many of the same attributes. So in each model I have to specify those same attributes and THEN the attributes that are specific to that particular model. Is there any way I can create some class that lists these basic attributes and then inherit from that class without using Single-Table Inheritance? Because if I put all the shared attributes and Mongoid includes into a single model and inherit from that base model in the other models, then STI is enforced and all my models are stored in a single mongodb collection, differentiated by a "_type" field. This is what I have: ``` class Model_1 include Mongoid::Document field :uuid, :type => String field :process_date, :type => String ... end class Model_2 include Mongoid::Document field :uuid, :type => String field :process_date, :type => String ... end ``` But this is the functionality I'm after: ``` class Base_model field :uuid, :type => String field :process_date, :type => String end class Model_1 < Base_model # To ensure STI is not enforced include Mongoid::Document # Attribute list inherited from Base_model end ``` The issue is that if you don't have the "include Mongoid::Document" in the Base_model, then that base model doesn't know about the "field ..." functionality. But if you do put the mongoid include in the base model and inherit from it, STI is enforced. I can't do STI for this particular situation but it's a coding nightmare to have multiple models, all with the same attributes list specified over and over (there are a growing number of models and each share about 15-20 attributes, so anytime I have to change a model name it's a lot of effort to change it everywhere...).