aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJessica Yao <jyao@college.harvard.edu>2014-04-21 18:08:54 -0400
committerMatthew Draper <matthew@trebex.net>2014-05-14 22:32:13 +0930
commit6de710d6648e451ef47e9215172901e8d736ba0c (patch)
tree11de776c60ea3f582ff3452a7f511453457e0a57
parent374d19a743f8b698ecb6d8d23d31dcf4325ddbcf (diff)
downloadrails-6de710d6648e451ef47e9215172901e8d736ba0c.tar.gz
rails-6de710d6648e451ef47e9215172901e8d736ba0c.tar.bz2
rails-6de710d6648e451ef47e9215172901e8d736ba0c.zip
Fix inheritance of stored_attributes (fixes #14672)
[Brad Bennett, Jessica Yao, & Lakshmi Parthasarathy]
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/store.rb19
-rw-r--r--activerecord/test/cases/store_test.rb16
3 files changed, 37 insertions, 5 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index f6cd5efb45..6d4ea2b682 100644
--- a/activerecord/CHANGELOG.md
+++ b/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*
+
* `change_column_default` allows `[]` as argument to `change_column_default`.
Fixes #11586.
diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb
index 79a6ccbda0..7014bc6d45 100644
--- a/activerecord/lib/active_record/store.rb
+++ b/activerecord/lib/active_record/store.rb
@@ -66,8 +66,9 @@ module ActiveRecord
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
@@ -93,9 +94,9 @@ module ActiveRecord
# 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
@@ -105,6 +106,14 @@ module ActiveRecord
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
diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb
index 978cee9cfb..6a34c55011 100644
--- a/activerecord/test/cases/store_test.rb
+++ b/activerecord/test/cases/store_test.rb
@@ -163,6 +163,22 @@ class StoreTest < ActiveRecord::TestCase
assert_equal [:width, :height], second_model.stored_attributes[:data]
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