Extends ancestry to allow attributes to be inherited from ancestors.

gem install inherited-attributes -v 0.1.1



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.


Tell your model that it has inherited attributes

class Node < ActiveRecord::Base

  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

class Account < ActiveRecord::Base
  belongs_to :node

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>


Add this line to your application's Gemfile:

gem 'inherited-attributes'

And then execute:

$ bundle

Or install it yourself as:

$ gem install inherited-attributes


  1. Fork the repo.

  2. 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

  3. 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!

  4. Make the test pass.

  5. Push to your fork and submit a pull request.


The gem is available as open source under the terms of the MIT License.