Skip to content
Permalink
Browse files

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
  • Loading branch information...
sgrif committed Jan 23, 2018
1 parent 6003daf commit 0af36c62a5710e023402e37b019ad9982e69de4b
@@ -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.
@@ -22,6 +22,28 @@ def with_type(type)
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
@@ -64,5 +64,14 @@ class GrandchildModelForAttributesTest < ChildModelForAttributesTest

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

0 comments on commit 0af36c6

Please sign in to comment.
You can’t perform that action at this time.