vidibus-inheritance¶ ↑
This gem is part of the open source SOA framework Vidibus: www.vidibus.org
It allows inheritance of objects and is depends on Rails 3 and Mongoid. It will update all attributes and embedded documents of inheritors when ancestor gets changed. Custom attributes (mutations) of inheritors will not be overridden, unless a :reset option is set.
Installation¶ ↑
Add the dependency to the Gemfile of your application:
gem "vidibus-inheritance"
Then call bundle install on your console.
Usage¶ ↑
Include the Vidibus::Uuid::Inheritance module in your Mongoid model:
class Model include Mongoid::Document include Vidibus::Uuid::Mongoid include Vidibus::Inheritance::Mongoid field :name end
To establish an inheritance relationship, add ancestor to a model of same class:
ancestor = Model.create(:name => "Anna") # To establish a relation, call #inherit_from! inheritor = Model.new inheritor.inherit_from!(ancestor) # ...or set :ancestor attribute inheritor = Model.create(:ancestor => ancestor)
Mongoid configuration¶ ↑
When inheriting, the attribute :_reference_id will be set on embedded documents of inherited objects. So make sure this field is available or Mongoid is configured to allow dynamic fields. Add to config/mongoid.yml:
allow_dynamic_fields: true
Acquired attributes¶ ↑
All attributes will be inherited, except these ACQUIRED_ATTRIBUTES:
_id _type uuid ancestor_uuid mutated_attributes mutated created_at updated_at version versions
You may overwrite acquired attributes by defining a method on your inherited document and its embedded documents:
def acquired_attributes Vidibus::Inheritance::Mongoid::ACQUIRED_ATTRIBUTES + %w[my custom values] end
Manage mutations of embedded documents¶ ↑
All custom changes on inherited objects will be stored in #mutated_attributes. On embedded documents of inherited objects, however, mutations of attributes will not be tracked. But you may flag a document as mutated when applying custom values:
class Job include Mongoid::Document field :salary field :mutated, :type => Boolean embedded_in :model, :inverse_of => :jobs def set_custom_salary(amount) self.salary = amount self.mutated = true end end
To control how inherited data will be updated, you may define a callback method and check #mutated:
def update_inherited_attributes(attrs) attrs.delete("salary") if mutated? # preserve custom salary update_attributes(attrs) end
TODO¶ ↑
-
Removed items will be re-added when inheritance is performed again. Introduce paranoid behaviour for embedded collection items? Or add a list of deleted associations like _destroyed_children?
-
Use delayed_job for inheritance across a huge pedigree.
-
Fix relations when deleting an ancestor.
-
Rewrite root_ancestor_id when deleting the root ancestor.
Copyright¶ ↑
Copyright © 2010 Andre Pankratz. See LICENSE for details.
Thank you!¶ ↑
The development of this gem was sponsored by Käuferportal: www.kaeuferportal.de