Skip to content

Commit

Permalink
Merge pull request #14833 from jyao6/attribute_inheritance
Browse files Browse the repository at this point in the history
Fixed Attribute Inheritance Issue

Conflicts:
	activerecord/CHANGELOG.md
  • Loading branch information
matthewd committed May 14, 2014
1 parent 69fc26f commit 2fe11e4
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
7 changes: 7 additions & 0 deletions 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`.
Expand Down
19 changes: 14 additions & 5 deletions activerecord/lib/active_record/store.rb
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
16 changes: 16 additions & 0 deletions activerecord/test/cases/store_test.rb
Expand Up @@ -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
Expand Down

0 comments on commit 2fe11e4

Please sign in to comment.