aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2018-01-23 14:08:46 -0700
committerSean Griffin <sean@seantheprogrammer.com>2018-01-23 14:12:13 -0700
commit0af36c62a5710e023402e37b019ad9982e69de4b (patch)
tree178cbe93ac6e6e2c489ac21a124c354e1300f20d /activemodel
parent6003dafc1f844275d6a7fe9e626eaeb1176c8e8a (diff)
downloadrails-0af36c62a5710e023402e37b019ad9982e69de4b.tar.gz
rails-0af36c62a5710e023402e37b019ad9982e69de4b.tar.bz2
rails-0af36c62a5710e023402e37b019ad9982e69de4b.zip
Allow attributes with a proc default to be marshalled
We don't implement much custom marshalling logic for these objects, but the proc default case needs to be handled separately. Unfortunately there's no way to just say "do what you would have done but with this value for one ivar", so we have to manually implement `marshal_load` as well. The test case is a little bit funky, but I'd really like an equality test in there, and there's no easy way to add one now that this is out of AR (since the `attributes` method isn't here) Fixes #31216
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/CHANGELOG.md7
-rw-r--r--activemodel/lib/active_model/attribute/user_provided_default.rb22
-rw-r--r--activemodel/test/cases/attributes_test.rb9
3 files changed, 38 insertions, 0 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index b67a803b9d..86353674d9 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,7 +1,14 @@
+* Models using the attributes API with a proc default can now be marshalled.
+
+ Fixes #31216.
+
+ *Sean Griffin*
+
* Fix to working before/after validation callbacks on multiple contexts.
*Yoshiyuki Hirano*
+
## Rails 5.2.0.beta2 (November 28, 2017) ##
* No changes.
diff --git a/activemodel/lib/active_model/attribute/user_provided_default.rb b/activemodel/lib/active_model/attribute/user_provided_default.rb
index f274b687d4..a5dc6188d2 100644
--- a/activemodel/lib/active_model/attribute/user_provided_default.rb
+++ b/activemodel/lib/active_model/attribute/user_provided_default.rb
@@ -22,6 +22,28 @@ module ActiveModel
self.class.new(name, user_provided_value, type, original_attribute)
end
+ def marshal_dump
+ result = [
+ name,
+ value_before_type_cast,
+ type,
+ original_attribute,
+ ]
+ result << value if defined?(@value)
+ result
+ end
+
+ def marshal_load(values)
+ name, user_provided_value, type, original_attribute, value = values
+ @name = name
+ @user_provided_value = user_provided_value
+ @type = type
+ @original_attribute = original_attribute
+ if values.length == 5
+ @value = value
+ end
+ end
+
protected
attr_reader :user_provided_value
diff --git a/activemodel/test/cases/attributes_test.rb b/activemodel/test/cases/attributes_test.rb
index e43bf15335..7c1d813ce0 100644
--- a/activemodel/test/cases/attributes_test.rb
+++ b/activemodel/test/cases/attributes_test.rb
@@ -64,5 +64,14 @@ module ActiveModel
assert_equal "4.4", data.integer_field
end
+
+ test "attributes with proc defaults can be marshalled" do
+ data = ModelForAttributesTest.new
+ attributes = data.instance_variable_get(:@attributes)
+ round_tripped = Marshal.load(Marshal.dump(data))
+ new_attributes = round_tripped.instance_variable_get(:@attributes)
+
+ assert_equal attributes, new_attributes
+ end
end
end