Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #14833 from jyao6/attribute_inheritance

Fixed Attribute Inheritance Issue

Conflicts:
	activerecord/CHANGELOG.md
  • Loading branch information...
commit 2fe11e4cddfa0b1e7faa199bfd2279fed3b55d48 1 parent 69fc26f
@matthewd matthewd authored
View
7 activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Fix `stored_attributes` to correctly merge the details of stored
+ attributes defined in parent classes.
+
+ Fixes #14672.
+
+ *Brad Bennett*, *Jessica Yao*, *Lakshmi Parthasarathy*
+
* Fix bug where `ActiveRecord::Store` used a global `Hash` to keep track of
all registered `stored_attributes`. Now every subclass of
`ActiveRecord::Base` has it's own `Hash`.
View
19 activerecord/lib/active_record/store.rb
@@ -61,8 +61,9 @@ module Store
extend ActiveSupport::Concern
included do
- class_attribute :stored_attributes, instance_accessor: false
- self.stored_attributes = {}
+ class << self
+ attr_accessor :local_stored_attributes
+ end
end
module ClassMethods
@@ -88,9 +89,9 @@ def store_accessor(store_attribute, *keys)
# assign new store attribute and create new hash to ensure that each class in the hierarchy
# has its own hash of stored attributes.
- self.stored_attributes = {} if self.stored_attributes.blank?
- self.stored_attributes[store_attribute] ||= []
- self.stored_attributes[store_attribute] |= keys
+ self.local_stored_attributes ||= {}
+ self.local_stored_attributes[store_attribute] ||= []
+ self.local_stored_attributes[store_attribute] |= keys
end
def _store_accessors_module
@@ -100,6 +101,14 @@ def _store_accessors_module
mod
end
end
+
+ def stored_attributes
+ parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {}
+ if self.local_stored_attributes
+ parent.merge!(self.local_stored_attributes) { |k, a, b| a | b }
+ end
+ parent
+ end
end
protected
View
16 activerecord/test/cases/store_test.rb
@@ -156,6 +156,22 @@ class StoreTest < ActiveRecord::TestCase
assert_raise(NoMethodError) { @john.stored_attributes }
end
+ test "stored_attributes are tracked per subclass" do
+ first_model = Class.new(ActiveRecord::Base) do
+ store_accessor :data, :color
+ end
+ second_model = Class.new(first_model) do
+ store_accessor :data, :width, :height
+ end
+ third_model = Class.new(first_model) do
+ store_accessor :data, :area, :volume
+ end
+
+ assert_equal [:color], first_model.stored_attributes[:data]
+ assert_equal [:color, :width, :height], second_model.stored_attributes[:data]
+ assert_equal [:color, :area, :volume], third_model.stored_attributes[:data]
+ end
+
test "YAML coder initializes the store when a Nil value is given" do
assert_equal({}, @john.params)
end
Please sign in to comment.
Something went wrong with that request. Please try again.