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.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:
def attribute_method_matchers #:nodoc: read_inheritable_attribute(:attribute_method_matchers) || write_inheritable_attribute(:attribute_method_matchers, []) end
def attribute_method_prefix(*prefixes)
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 # => "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?
def attribute_methods_generated? @attribute_methods_generated ||= nil end
def define_attr_method(name, value=nil, &block)
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
...
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:
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
def undefine_attribute_methods generated_attribute_methods.module_eval do instance_methods.each { |m| undef_method(m) } end @attribute_methods_generated = nil end