mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixed issue w/custom accessors + reserved name + inheritance
Fixed an issue where custom accessor methods (such as those generated by `enum`) with the same name as a global method are incorrectly overridden when subclassing. This was partially fixed in4155431
then broken again bye5f15a8
. Fixes #16288.
This commit is contained in:
parent
49798b52bf
commit
2638d5c724
3 changed files with 34 additions and 5 deletions
|
@ -1,3 +1,11 @@
|
|||
* Fixed an issue where custom accessor methods (such as those generated by
|
||||
`enum`) with the same name as a global method are incorrectly overridden
|
||||
when subclassing.
|
||||
|
||||
Fixes #16288.
|
||||
|
||||
*Godfrey Chan*
|
||||
|
||||
* Define `id_was` to get the previous value of the primary key.
|
||||
|
||||
Currently when we call id_was and we have a custom primary key name
|
||||
|
|
|
@ -57,6 +57,8 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class GeneratedAttributeMethods < Module; end # :nodoc:
|
||||
|
||||
module ClassMethods
|
||||
def inherited(child_class) #:nodoc:
|
||||
child_class.initialize_generated_modules
|
||||
|
@ -64,7 +66,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def initialize_generated_modules # :nodoc:
|
||||
@generated_attribute_methods = Module.new { extend Mutex_m }
|
||||
@generated_attribute_methods = GeneratedAttributeMethods.new { extend Mutex_m }
|
||||
@attribute_methods_generated = false
|
||||
include @generated_attribute_methods
|
||||
end
|
||||
|
@ -113,10 +115,11 @@ module ActiveRecord
|
|||
if superclass == Base
|
||||
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)
|
||||
base_defined = Base.method_defined?(method_name) || Base.private_method_defined?(method_name)
|
||||
defined && !base_defined || super
|
||||
# If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass
|
||||
# defines its own attribute method, then we don't want to overwrite that.
|
||||
defined = method_defined_within?(method_name, superclass, Base) &&
|
||||
! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
|
||||
defined || super
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -810,6 +810,24 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|||
assert_equal "lol", topic.author_name
|
||||
end
|
||||
|
||||
def test_inherited_custom_accessors_with_reserved_names
|
||||
klass = Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'computers'
|
||||
self.abstract_class = true
|
||||
def system; "omg"; end
|
||||
def system=(val); self.developer = val; end
|
||||
end
|
||||
|
||||
subklass = Class.new(klass)
|
||||
[klass, subklass].each(&:define_attribute_methods)
|
||||
|
||||
computer = subklass.find(1)
|
||||
assert_equal "omg", computer.system
|
||||
|
||||
computer.developer = 99
|
||||
assert_equal 99, computer.developer
|
||||
end
|
||||
|
||||
def test_on_the_fly_super_invokable_generated_attribute_methods_via_method_missing
|
||||
klass = new_topic_like_ar_class do
|
||||
def title
|
||||
|
|
Loading…
Reference in a new issue