Make ActiveModel::Errors backward compatible with 4.2

If a Error object was serialized in the database as YAML in the Rails
4.2 version, if we load in the Rails 5.0 version it will miss the
@details instance variable so methods like #clear and #add will start to
fail.
This commit is contained in:
Rafael Mendonça França 2016-12-08 16:20:07 -05:00
parent deaaf80524
commit 0951306ca5
No known key found for this signature in database
GPG Key ID: FC23B6D0F1EEE948
2 changed files with 29 additions and 2 deletions

View File

@ -419,16 +419,23 @@ module ActiveModel
I18n.translate(key, options)
end
def marshal_dump
def marshal_dump # :nodoc:
[@base, without_default_proc(@messages), without_default_proc(@details)]
end
def marshal_load(array)
def marshal_load(array) # :nodoc:
@base, @messages, @details = array
apply_default_array(@messages)
apply_default_array(@details)
end
def init_with(coder) # :nodoc:
coder.map.each { |k, v| instance_variable_set(:"@#{k}", v) }
@details ||= {}
apply_default_array(@messages)
apply_default_array(@details)
end
private
def normalize_message(attribute, message, options)
case message

View File

@ -365,4 +365,24 @@ class ErrorsTest < ActiveModel::TestCase
assert_equal errors.messages, serialized.messages
assert_equal errors.details, serialized.details
end
test "errors are backward compatible with the Rails 4.2 format" do
yaml = <<-CODE.strip_heredoc
--- !ruby/object:ActiveModel::Errors
base: &1 !ruby/object:ErrorsTest::Person
errors: !ruby/object:ActiveModel::Errors
base: *1
messages: {}
messages: {}
CODE
errors = YAML.load(yaml)
errors.add(:name, :invalid)
assert_equal({ name: ["is invalid"] }, errors.messages)
assert_equal({ name: [{ error: :invalid }] }, errors.details)
errors.clear
assert_equal({}, errors.messages)
assert_equal({}, errors.details)
end
end