diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-12-04 15:50:31 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-12-04 15:50:31 -0700 |
commit | d1f003e67b6438a0c5367962fa1a35cd22e7cc8c (patch) | |
tree | 477fba294e0701df58387306c4e3b5b1707a43fe /activemodel | |
parent | 08ff4ccbbb3fb143a02e6752efb974a4bcfcd3bb (diff) | |
download | rails-d1f003e67b6438a0c5367962fa1a35cd22e7cc8c.tar.gz rails-d1f003e67b6438a0c5367962fa1a35cd22e7cc8c.tar.bz2 rails-d1f003e67b6438a0c5367962fa1a35cd22e7cc8c.zip |
Correctly handle multiple attribute method prefix/suffixes which match
Active Record defines `attribute_method_suffix :?`. That suffix will
match any predicate method when the lookup occurs in Active Model. This
will make it incorrectly decide that `id_changed?` should not exist,
because it attempts to determine if the attribute `id_changed` is
present, rather than `id` with the `_changed?` suffix. Instead, we will
look for any correct match.
Diffstat (limited to 'activemodel')
-rw-r--r-- | activemodel/lib/active_model/attribute_methods.rb | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index ea07c5c039..96be551264 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -353,14 +353,12 @@ module ActiveModel @attribute_method_matchers_cache ||= ThreadSafe::Cache.new(initial_capacity: 4) end - def attribute_method_matcher(method_name) #:nodoc: + def attribute_method_matchers_matching(method_name) #:nodoc: attribute_method_matchers_cache.compute_if_absent(method_name) do # Must try to match prefixes/suffixes first, or else the matcher with no prefix/suffix # will match every time. matchers = attribute_method_matchers.partition(&:plain?).reverse.flatten(1) - match = nil - matchers.detect { |method| match = method.match(method_name) } - match + matchers.map { |method| method.match(method_name) }.compact end end @@ -469,8 +467,8 @@ module ActiveModel # Returns a struct representing the matching attribute method. # The struct's attributes are prefix, base and suffix. def match_attribute_method?(method_name) - match = self.class.send(:attribute_method_matcher, method_name) - match if match && attribute_method?(match.attr_name) + matches = self.class.send(:attribute_method_matchers_matching, method_name) + matches.detect { |match| attribute_method?(match.attr_name) } end def missing_attribute(attr_name, stack) |