Inherited::Attributes
Extends ancestry to allow attributes to be inherited from ancestors.
When you want nodes in your tree to be able to get default values for their attributes from their parent.
Usage
Tell your model that it has inherited attributes
class Node < ActiveRecord::Base
has_ancestry
inherited_attribute :value
# If the root node has a nil location, use this as the default value instead.
# Note the special syntax - the default value is evaluated.
# strings: '"<the default>"'
# booleans: '<true|false>'
# integers: '<number>'
# enumerations: '"<name of the enum>"'
inherited_attribute :location, :default => '"Saint Louis"'
# Has-one relationships can also be inherited.
# With delegation, you can expose attributes on the effective or inherited account
# Or you can use the effective_account to get the inherited object
has_one :account
inherited_attribute :account
delegate :name, :to => :account, :prefix => true, :allow_nil => true
delegate :name, :to => :effective_account, :prefix => true, :allow_nil => true
delegate :name, :to => :inherited_account, :prefix => true, :allow_nil => true
end
class Account < ActiveRecord::Base
belongs_to :node
end
Accessing Inherited Attributes
root = Node.create!
child = Node.create!(:parent => root, :value => 12, :location => "Boston")
grandchild = Node.create!(:parent => child)
# ------------------------------------------------------------------------------
# The value of the node, without ancestry
# ------------------------------------------------------------------------------
root.value # nil
child.value # 12
grandchild.value # nil
root.location #
child.location # 'Boston'
grandchild.location # nil
# ------------------------------------------------------------------------------
# The value of the node, or the inherited value if its not set
# ------------------------------------------------------------------------------
root.effective_value # nil
child.effective_value # 12
grandchild.effective_value # 12 -- inherited from child
root.effective_location # 'Saint Louis' -- using the default value
child.effective_location # 'Boston' -- Using the node's value
grandchild.effective_location # 'Boston' -- Inherited from child
# ------------------------------------------------------------------------------
# The inherited value of the node or the default, ignoring the node's value
# ------------------------------------------------------------------------------
root.inherited_value # nil
child.inherited_value # nil
grandchild.inherited_value # 12 -- inherited from child
root.inherited_location # 'Saint Louis' -- using the default value
child.inherited_location # 'Saint Louis' -- Inherited from root
grandchild.inherited_location # 'Boston' -- Inherited from child
# ------------------------------------------------------------------------------
# Inherited Has-One relationships and attributes
# ------------------------------------------------------------------------------
child.create_account(:name => "Cash")
root.effective_account_name # nil
child.effective_account_name # 'Cash'
grandchild.effective_account_name # 'Cash' -- Inherited from child
root.effective_account # nil
child.effective_account # <#<Account:0x007fb561759b58 id: 1, name: "Cash", node_id: 2>
grandchild.effective_account # <#<Account:0x007fb561759b58 id: 1, name: "Cash", node_id: 2>
Installation
Add this line to your application's Gemfile:
gem 'inherited-attributes'
And then execute:
$ bundle
Or install it yourself as:
$ gem install inherited-attributes
Contributing
-
Fork the repo.
-
Run the tests (appraisal rake spec). We only take pull requests with passing tests, and it's great to know that you have a clean slate:
bundle && rake
-
Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, we need a test!
-
Make the test pass.
-
Push to your fork and submit a pull request.
License
The gem is available as open source under the terms of the MIT License.