76 lines
2.3 KiB
Ruby
76 lines
2.3 KiB
Ruby
|
module ActiveRecord
|
||
|
module AttributeMethods #:nodoc:
|
||
|
DEFAULT_SUFFIXES = %w(= ? _before_type_cast)
|
||
|
|
||
|
def self.included(base)
|
||
|
base.extend ClassMethods
|
||
|
base.attribute_method_suffix *DEFAULT_SUFFIXES
|
||
|
end
|
||
|
|
||
|
# Declare and check for suffixed attribute methods.
|
||
|
module ClassMethods
|
||
|
# Declare a method available for all attributes with the given suffix.
|
||
|
# Uses method_missing and respond_to? to rewrite the method
|
||
|
# #{attr}#{suffix}(*args, &block)
|
||
|
# to
|
||
|
# attribute#{suffix}(#{attr}, *args, &block)
|
||
|
#
|
||
|
# An attribute#{suffix} instance method must exist and accept at least
|
||
|
# the attr argument.
|
||
|
#
|
||
|
# For example:
|
||
|
# class Person < ActiveRecord::Base
|
||
|
# attribute_method_suffix '_changed?'
|
||
|
#
|
||
|
# private
|
||
|
# def attribute_changed?(attr)
|
||
|
# ...
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# person = Person.find(1)
|
||
|
# person.name_changed? # => false
|
||
|
# person.name = 'Hubert'
|
||
|
# person.name_changed? # => true
|
||
|
def attribute_method_suffix(*suffixes)
|
||
|
attribute_method_suffixes.concat suffixes
|
||
|
rebuild_attribute_method_regexp
|
||
|
end
|
||
|
|
||
|
# Returns MatchData if method_name is an attribute method.
|
||
|
def match_attribute_method?(method_name)
|
||
|
rebuild_attribute_method_regexp unless defined?(@@attribute_method_regexp) && @@attribute_method_regexp
|
||
|
@@attribute_method_regexp.match(method_name)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
# Suffixes a, ?, c become regexp /(a|\?|c)$/
|
||
|
def rebuild_attribute_method_regexp
|
||
|
suffixes = attribute_method_suffixes.map { |s| Regexp.escape(s) }
|
||
|
@@attribute_method_regexp = /(#{suffixes.join('|')})$/.freeze
|
||
|
end
|
||
|
|
||
|
# Default to =, ?, _before_type_cast
|
||
|
def attribute_method_suffixes
|
||
|
@@attribute_method_suffixes ||= []
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
# Handle *? for method_missing.
|
||
|
def attribute?(attribute_name)
|
||
|
query_attribute(attribute_name)
|
||
|
end
|
||
|
|
||
|
# Handle *= for method_missing.
|
||
|
def attribute=(attribute_name, value)
|
||
|
write_attribute(attribute_name, value)
|
||
|
end
|
||
|
|
||
|
# Handle *_before_type_cast for method_missing.
|
||
|
def attribute_before_type_cast(attribute_name)
|
||
|
read_attribute_before_type_cast(attribute_name)
|
||
|
end
|
||
|
end
|
||
|
end
|