module ActiveAttr::AttributeDefaults

AttributeDefaults allows defaults to be declared for your attributes

Defaults are declared by passing the :default option to the attribute class method. If you need the default to be dynamic, pass a lambda, Proc, or any object that responds to call as the value to the :default option and the result will calculated on initialization. These dynamic defaults can depend on the values of other attributes when those attributes are assigned using MassAssignment or BlockInitialization.

@example Usage

class Person
  include ActiveAttr::AttributeDefaults

  attribute :first_name, :default => "John"
  attribute :last_name, :default => "Doe"
end

person = Person.new
person.first_name #=> "John"
person.last_name #=> "Doe"

@example Dynamic Default

class Event
  include ActiveAttr::MassAssignment
  include ActiveAttr::AttributeDefaults

  attribute :start_date
  attribute :end_date, :default => lambda { start_date }
end

event = Event.new(:start_date => Date.parse("2012-01-01"))
event.end_date.to_s #=> "2012-01-01"

@since 0.5.0

Public Class Methods

new(*) click to toggle source

Applies attribute default values

@since 0.5.0

# File lib/active_attr/attribute_defaults.rb, line 99
def initialize(*)
  super
  apply_defaults
end

Public Instance Methods

apply_defaults(defaults=attribute_defaults) click to toggle source

Applies the attribute defaults

Applies all the default values to any attributes not yet set, avoiding any attribute setter logic, such as dirty tracking.

@example Usage

class Person
  include ActiveAttr::AttributeDefaults

  attribute :first_name, :default => "John"

  def reset!
    @attributes = {}
    apply_defaults
  end
end

person = Person.new(:first_name => "Chris")
person.reset!
person.first_name #=> "John"

@param [Hash{String => Object}, each] defaults The defaults to apply

@since 0.5.0

# File lib/active_attr/attribute_defaults.rb, line 70
def apply_defaults(defaults=attribute_defaults)
  @attributes ||= {}
  defaults.each do |name, value|
    # instance variable is used here to avoid any dirty tracking in attribute setter methods
    @attributes[name] = value unless @attributes.has_key? name
  end
end
attribute_defaults() click to toggle source

Calculates the attribute defaults from the attribute definitions

@example Usage

class Person
  include ActiveAttr::AttributeDefaults

  attribute :first_name, :default => "John"
end

Person.new.attribute_defaults #=> {"first_name"=>"John"}

@return [Hash{String => Object}] the attribute defaults

@since 0.5.0

# File lib/active_attr/attribute_defaults.rb, line 92
def attribute_defaults
  attributes_map { |name| _attribute_default name }
end

Private Instance Methods

_attribute_default(attribute_name) click to toggle source

Calculates an attribute default

@private @since 0.5.0

# File lib/active_attr/attribute_defaults.rb, line 110
def _attribute_default(attribute_name)
  default = self.class.attributes[attribute_name][:default]

  case
  when default.respond_to?(:call) then instance_exec(&default)
  when default.duplicable? then default.dup
  else default
  end
end