aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2016-05-30 14:00:14 -0400
committerSean Griffin <sean@seantheprogrammer.com>2016-05-30 14:04:29 -0400
commitb3dfd7d16cc37dcaf4298fe42e69a56ab3c6b00e (patch)
treea98a6e09e2067bb4a0505b2d744364f0adb04283 /activemodel/lib
parent88f763b047875483be10f554bc15278b28c86a8c (diff)
downloadrails-b3dfd7d16cc37dcaf4298fe42e69a56ab3c6b00e.tar.gz
rails-b3dfd7d16cc37dcaf4298fe42e69a56ab3c6b00e.tar.bz2
rails-b3dfd7d16cc37dcaf4298fe42e69a56ab3c6b00e.zip
Ensure that instances of `ActiveModel::Errors` can be marshalled
We now use default procs inside of the errors object, which gets included by default when marshaling anything that includes `ActiveModel::Validations`. This means that Active Record objects cannot be marshalled. We strip and apply the default proc ourselves. This will ensure the objects are YAML serializable as well, since YAML falls back to marshal implementations now. This is less important, however, as the errors aren't included when dumping Active Record objects. This commit does not include a changelog entry, as 5.0 is still in RC status at the time of writing, and 5.0.0 will not release with the bug this fixes. Fixes #25165
Diffstat (limited to 'activemodel/lib')
-rw-r--r--activemodel/lib/active_model/errors.rb25
1 files changed, 23 insertions, 2 deletions
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 696e6d31da..6f2c8c1c53 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -71,8 +71,8 @@ module ActiveModel
# end
def initialize(base)
@base = base
- @messages = Hash.new { |messages, attribute| messages[attribute] = [] }
- @details = Hash.new { |details, attribute| details[attribute] = [] }
+ @messages = apply_default_array({})
+ @details = apply_default_array({})
end
def initialize_dup(other) # :nodoc:
@@ -493,6 +493,16 @@ module ActiveModel
I18n.translate(key, options)
end
+ def marshal_dump
+ [@base, without_default_proc(@messages), without_default_proc(@details)]
+ end
+
+ def marshal_load(array)
+ @base, @messages, @details = array
+ apply_default_array(@messages)
+ apply_default_array(@details)
+ end
+
private
def normalize_message(attribute, message, options)
case message
@@ -506,6 +516,17 @@ module ActiveModel
def normalize_detail(message, options)
{ error: message }.merge(options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS))
end
+
+ def without_default_proc(hash)
+ hash.dup.tap do |new_h|
+ new_h.default_proc = nil
+ end
+ end
+
+ def apply_default_array(hash)
+ hash.default_proc = proc { |h, key| h[key] = [] }
+ hash
+ end
end
# Raised when a validation cannot be corrected by end users and are considered