diff options
author | Godfrey Chan <godfreykfc@gmail.com> | 2014-02-13 11:49:19 -0800 |
---|---|---|
committer | Godfrey Chan <godfreykfc@gmail.com> | 2014-02-23 11:00:55 -0800 |
commit | 41554319f8454f667b5e315339d3e286dbf6e1a4 (patch) | |
tree | 6b429827488b2ca7f34095d5f74f208ea6a8301f /activerecord/lib | |
parent | 96759cf6c6a17053abb6a2b7cd87cdbd5a8420ba (diff) | |
download | rails-41554319f8454f667b5e315339d3e286dbf6e1a4.tar.gz rails-41554319f8454f667b5e315339d3e286dbf6e1a4.tar.bz2 rails-41554319f8454f667b5e315339d3e286dbf6e1a4.zip |
Fixed STI classes not defining an attribute method if there is a
conflicting private method defined on its ancestors.
The problem is that `method_defined_within?(name, klass, superklass)`
only works correclty when `klass` and `superklass` are both `Class`es.
If both `klass` and `superklass` are both `Class`es, they share the
same inheritance chain, so if a method is defined on `klass` but not
`superklass`, this method must be introduced at some point between
`klass` and `superklass`.
This does not work when `superklass` is a `Module`. A `Module`'s
inheritance chain contains just itself. So if a method is defined on
`klass` but not on `superklass`, the method could still be defined
somewhere upstream, e.g. in `Object`.
This fix works by avoiding calling `method_defined_within?` with a
module while still fufilling the requirement (checking that the
method is defined withing `superclass` but not is not a generated
attribute method).
4d8ee288 is likely an attempted partial fix for this problem. This
unrolls that fix and properly check the `superclass` as intended.
Fixes #11569.
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/attribute_methods.rb | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 9326c9c117..57ceec2fc5 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -105,8 +105,9 @@ module ActiveRecord super else # If B < A and A defines its own attribute method, then we don't want to overwrite that. - defined = method_defined_within?(method_name, superclass, superclass.generated_attribute_methods) - defined && !ActiveRecord::Base.method_defined?(method_name) || super + defined = method_defined_within?(method_name, superclass) && + superclass.instance_method(method_name).owner != superclass.generated_attribute_methods + defined || super end end |