From d60d7edce462f4602bfc9996689087a235b034c9 Mon Sep 17 00:00:00 2001 From: Sam Goldstein Date: Wed, 8 Jul 2009 11:45:26 -0700 Subject: Make it so AR attributes which conflict with object-private methods (e.g. system) don't 'randomly' cause NoMethodErrors Previously if you called this attribute before others, you'd get exceptions. But if it was the second-or-subsequent attribute you retrieved you'd get the correct behaviour. Signed-off-by: Michael Koziarski [#2808 state:committed] --- activerecord/lib/active_record/attribute_methods.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 15358979c2..ecd2d57a5a 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -133,6 +133,7 @@ module ActiveRecord end private + # Suffixes a, ?, c become regexp /(a|\?|c)$/ def rebuild_attribute_method_regexp suffixes = attribute_method_suffixes.map { |s| Regexp.escape(s) } @@ -238,19 +239,17 @@ module ActiveRecord def method_missing(method_id, *args, &block) method_name = method_id.to_s - if self.class.private_method_defined?(method_name) - raise NoMethodError.new("Attempt to call private method", method_name, args) - end - # If we haven't generated any methods yet, generate them, then # see if we've created the method we're looking for. if !self.class.generated_methods? self.class.define_attribute_methods + guard_private_attribute_method!(method_name, args) if self.class.generated_methods.include?(method_name) return self.send(method_id, *args, &block) end end + guard_private_attribute_method!(method_name, args) if self.class.primary_key.to_s == method_name id elsif md = self.class.match_attribute_method?(method_name) @@ -371,6 +370,12 @@ module ActiveRecord end private + # prevent method_missing from calling private methods with #send + def guard_private_attribute_method!(method_name, args) + if self.class.private_method_defined?(method_name) + raise NoMethodError.new("Attempt to call private method", method_name, args) + end + end def missing_attribute(attr_name, stack) raise ActiveRecord::MissingAttributeError, "missing attribute: #{attr_name}", stack -- cgit v1.2.3