aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2006-07-31 03:43:03 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2006-07-31 03:43:03 +0000
commit2b3cc2478fff77fdada9adeabc32ecea0605d7bd (patch)
tree7aa6ba106ffefa4c571eb7edfe7ca1eabb31b41d /activerecord/lib/active_record/attribute_methods.rb
parentefff453148b4bd2d35d91a3d8344a7bad56da7c3 (diff)
downloadrails-2b3cc2478fff77fdada9adeabc32ecea0605d7bd.tar.gz
rails-2b3cc2478fff77fdada9adeabc32ecea0605d7bd.tar.bz2
rails-2b3cc2478fff77fdada9adeabc32ecea0605d7bd.zip
r4854@ks: jeremy | 2006-07-30 00:59:18 -0700
Attribute methods r4877@ks: jeremy | 2006-07-30 20:23:53 -0700 Factor the attribute#{suffix} methods out of method_missing for easier extension. r4878@ks: jeremy | 2006-07-30 20:42:23 -0700 More specific method naming, declare many attribute method suffixes, set up default suffixes at module include rather than lazily. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4632 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods.rb')
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb75
1 files changed, 75 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
new file mode 100644
index 0000000000..adc6eb6559
--- /dev/null
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -0,0 +1,75 @@
+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