diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 047688aba82a76ca69d914044e72264510c9f0df..20db6fb048eae3ddf6b1caed2acc533c64d16e6c 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,31 @@ +* Fix `thread_mattr_accessor` subclass no longer overwrites parent. + + Assigning a value to a subclass using `thread_mattr_accessor` no + longer changes the value of the parent class. This brings the + behavior inline with the documentation. + + Given: + + class Account + thread_mattr_accessor :user + end + + class Customer < Account + end + + Account.user = "DHH" + Customer.user = "Rafael" + + Before: + + Account.user # => "Rafael" + + After: + + Account.user # => "DHH" + + *Shinichi Maeshima* + * Since weeks are no longer converted to days, add `:weeks` to the list of parts that `ActiveSupport::TimeWithZone` will recognize as possibly being of variable duration to take account of DST transitions. diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb index 1ebae1f4f3568a00bc98ba11b2d64c79043443a5..a40f0df9e250fb7b77c8dbb23a1c3aea7a4a528a 100644 --- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb @@ -41,14 +41,14 @@ def thread_mattr_reader(*syms) raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym} - Thread.current[:"attr_#{name}_#{sym}"] + Thread.current["attr_"+ name + "_#{sym}"] end EOS unless options[:instance_reader] == false || options[:instance_accessor] == false class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym} - Thread.current[:"attr_#{name}_#{sym}"] + Thread.current["attr_"+ self.class.name + "_#{sym}"] end EOS end @@ -80,14 +80,14 @@ def thread_mattr_writer(*syms) raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym}=(obj) - Thread.current[:"attr_#{name}_#{sym}"] = obj + Thread.current["attr_"+ name + "_#{sym}"] = obj end EOS unless options[:instance_writer] == false || options[:instance_accessor] == false class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym}=(obj) - Thread.current[:"attr_#{name}_#{sym}"] = obj + Thread.current["attr_"+ self.class.name + "_#{sym}"] = obj end EOS end diff --git a/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb b/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb index cda5a344422ba52ade4e5b720ec74a536062021e..b816fa50e35676a8825d89bd78c680398d5e488e 100644 --- a/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb +++ b/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb @@ -8,6 +8,12 @@ def setup thread_mattr_accessor :bar, instance_writer: false thread_mattr_reader :shaq, instance_reader: false thread_mattr_accessor :camp, instance_accessor: false + + def self.name; "MyClass" end + end + + @subclass = Class.new(@class) do + def self.name; "SubMyClass" end end @object = @class.new @@ -112,4 +118,14 @@ def test_should_return_same_value_by_class_or_instance_accessor assert_equal @class.foo, @object.foo end + + def test_should_not_affect_superclass_if_subclass_set_value + @class.foo = "super" + assert_equal @class.foo, "super" + assert_nil @subclass.foo + + @subclass.foo = "sub" + assert_equal @class.foo, "super" + assert_equal @subclass.foo, "sub" + end end