module ActiveModel::AttributeMethods::ClassMethods

def alias_attribute(new_name, old_name)

def alias_attribute(new_name, old_name)
  attribute_method_matchers.each do |matcher|
    matcher_new = matcher.method_name(new_name).to_s
    matcher_old = matcher.method_name(old_name).to_s
    if matcher_new =~ COMPILABLE_REGEXP && matcher_old =~ COMPILABLE_REGEXP
      module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{matcher_new}(*args)
          send(:#{matcher_old}, *args)
        end
      RUBY
    else
      define_method(matcher_new) do |*args|
        send(matcher_old, *args)
      end
    end
  end
end

def attribute_method_affix(*affixes)

person.name # => 'Gemma'
person.reset_name_to_default!
person.name # => 'Gem'
person = Person.new

end
end
...
def reset_attribute_to_default!(attr)

private

define_attribute_methods [:name]
attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
attr_accessor :name
include ActiveModel::AttributeMethods

class Person

For example:

accept at least the +attr+ argument.
An #{prefix}attribute#{suffix} instance method must exist and

#{prefix}attribute#{suffix}(#{attr}, *args, &block)

to

#{prefix}#{attr}#{suffix}(*args, &block)

the method.
and suffix. Uses +method_missing+ and respond_to? to rewrite
Declares a method available for all attributes with the given prefix
def attribute_method_affix(*affixes)
  attribute_method_matchers.concat(affixes.map { |affix| AttributeMethodMatcher.new :prefix => affix[:prefix], :suffix => affix[:suffix] })
  undefine_attribute_methods
end

def attribute_method_matchers #:nodoc:

:nodoc:
def attribute_method_matchers #:nodoc:
  read_inheritable_attribute(:attribute_method_matchers) || write_inheritable_attribute(:attribute_method_matchers, [])
end

def attribute_method_prefix(*prefixes)

person.name # => nil
person.clear_name
person.name # => "Bob"
person.name = "Bob"
person = Person.new

end
end
send("#{attr}=", nil)
def clear_attribute(attr)

private

define_attribute_methods [:name]
attribute_method_prefix 'clear_'
attr_accessor :name
include ActiveModel::AttributeMethods

class Person

For example:

at least the +attr+ argument.
An instance method #{prefix}attribute must exist and accept

#{prefix}attribute(#{attr}, *args, &block)

to

#{prefix}#{attr}(*args, &block)

Uses +method_missing+ and respond_to? to rewrite the method.
Declares a method available for all attributes with the given prefix.
def attribute_method_prefix(*prefixes)
  attribute_method_matchers.concat(prefixes.map { |prefix| AttributeMethodMatcher.new :prefix => prefix })
  undefine_attribute_methods
end

def attribute_method_suffix(*suffixes)

person.name_short? # => true
person.name # => "Bob"
person.name = "Bob"
person = Person.new

end
end
send(attr).length < 5
def attribute_short?(attr)

private

define_attribute_methods [:name]
attribute_method_suffix '_short?'
attr_accessor :name
include ActiveModel::AttributeMethods

class Person

For example:

the +attr+ argument.
An attribute#{suffix} instance method must exist and accept at least

attribute#{suffix}(#{attr}, *args, &block)

to

#{attr}#{suffix}(*args, &block)

Uses +method_missing+ and respond_to? to rewrite the method.
Declares a method available for all attributes with the given suffix.
def attribute_method_suffix(*suffixes)
  attribute_method_matchers.concat(suffixes.map { |suffix| AttributeMethodMatcher.new :suffix => suffix })
  undefine_attribute_methods
end

def attribute_methods_generated?

Returns true if the attribute methods defined have been generated.
def attribute_methods_generated?
  @attribute_methods_generated ||= nil
end

def define_attr_method(name, value=nil, &block)

# => 'address_id'
AttributePerson.inheritance_column
AttributePerson.inheritance_column = 'address'
# => "sysid"
AttributePerson.primary_key

Provides you with:

end

end
original_inheritance_column + "_id"
define_attr_method( :inheritance_column ) do
define_attr_method :primary_key, "sysid"

cattr_accessor :inheritance_column
cattr_accessor :primary_key

include ActiveModel::AttributeMethods

class Person

Example:

value.
with "original_". This allows the new method to access the original
The original method will be aliased, with the new name being prefixed

method.
Otherwise, the given block will be used to compute the value of the
specified, the new method will return that value (as a string).
A new (class) method will be created with the given name. If a value is
Defines an "attribute" method (like +inheritance_column+ or +table_name+).
def define_attr_method(name, value=nil, &block)
  sing = singleton_class
  sing.class_eval <<-eorb, __FILE__, __LINE__ + 1
    if method_defined?(:'original_#{name}')
      undef :'original_#{name}'
    end
    alias_method :'original_#{name}', :'#{name}'
  eorb
  if block_given?
    sing.send :define_method, name, &block
  else
    # If we can compile the method name, do it. Otherwise use define_method.
    # This is an important *optimization*, please don't change it. define_method
    # has slower dispatch and consumes more memory.
    if name =~ COMPILABLE_REGEXP
      sing.class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{name}; #{value.nil? ? 'nil' : value.to_s.inspect}; end
      RUBY
    else
      value = value.to_s if value
      sing.send(:define_method, name) { value }
    end
  end
end

def define_attribute_methods(attr_names)

end
end
...
def clear_attribute(attr)

private

define_attribute_methods [:name, :age, :address]
# attribute_method_affix declares.
# attribute_method_prefix, attribute_method_suffix or
# Call to define_attribute_methods must appear after the

attribute_method_prefix 'clear_'
attr_accessor :name, :age, :address
include ActiveModel::AttributeMethods

class Person

prefix, suffix or affix methods, or they will not hook in.
be sure to declare +define_attribute_methods+ after you define any
To use, pass in an array of attribute names (as strings or symbols),

ActiveModel::AttributeMethods.
Declares a the attributes that should be prefixed and suffixed by
def define_attribute_methods(attr_names)
  return if attribute_methods_generated?
  attr_names.each do |attr_name|
    attribute_method_matchers.each do |matcher|
      unless instance_method_already_implemented?(matcher.method_name(attr_name))
        generate_method = "define_method_#{matcher.prefix}attribute#{matcher.suffix}"
        if respond_to?(generate_method)
          send(generate_method, attr_name)
        else
          method_name = matcher.method_name(attr_name)
          generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
            if method_defined?('#{method_name}')
              undef :'#{method_name}'
            end
          RUBY
          if method_name.to_s =~ COMPILABLE_REGEXP
            generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
              def #{method_name}(*args)
                send(:#{matcher.method_missing_target}, '#{attr_name}', *args)
              end
            RUBY
          else
            generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
              define_method('#{method_name}') do |*args|
                send('#{matcher.method_missing_target}', '#{attr_name}', *args)
              end
            RUBY
          end
        end
      end
    end
  end
  @attribute_methods_generated = true
end

def generated_attribute_methods #:nodoc:

:nodoc:
Returns true if the attribute methods defined have been generated.
def generated_attribute_methods #:nodoc:
  @generated_attribute_methods ||= begin
    mod = Module.new
    include mod
    mod
  end
end

def instance_method_already_implemented?(method_name)

def instance_method_already_implemented?(method_name)
  method_defined?(method_name)
end

def undefine_attribute_methods

Removes all the previously dynamically defined methods from the class
def undefine_attribute_methods
  generated_attribute_methods.module_eval do
    instance_methods.each { |m| undef_method(m) }
  end
  @attribute_methods_generated = nil
end