Fix FrozenError on ActiveModel::Error clear and delete

This PR fixes a `FrozenError` when attempting to clear or delete
`ActiveModel::Errors` through the deprecated array methods. In
particular the error happens in the following situations:

    # calling `clear` on the deprecated array
    errors[:some_attribute].clear

    # calling `delete` on the deprecated messages hash
    errors.messages.delete(:some_attribute)

Following the recent introduction of `ActiveModel::Error`, this PR adds
deprecation warnings for those two messages.
This commit is contained in:
Enrique Gonzalez 2019-08-29 22:41:39 -04:00
parent ffd74f58b0
commit 65f2180f19
2 changed files with 30 additions and 0 deletions

View File

@ -569,6 +569,12 @@ module ActiveModel
__setobj__ prepare_content
end
def delete(attribute)
ActiveSupport::Deprecation.warn("Calling `delete` to an ActiveModel::Errors messages hash is deprecated. Please call `ActiveModel::Errors#delete` instead.")
@errors.delete(attribute)
end
private
def prepare_content
content = @errors.to_hash
@ -599,6 +605,12 @@ module ActiveModel
__setobj__ @errors.messages_for(@attribute)
self
end
def clear
ActiveSupport::Deprecation.warn("Calling `clear` to an ActiveModel::Errors message array in order to delete all errors is deprecated. Please call `ActiveModel::Errors#delete` instead.")
@errors.delete(@attribute)
end
end
class DeprecationHandlingDetailsHash < SimpleDelegator

View File

@ -103,6 +103,15 @@ class ErrorsTest < ActiveModel::TestCase
assert_empty person.errors
end
test "clear errors by key" do
person = Person.new
person.validate!
assert_equal 1, person.errors.count
assert_deprecated { person.errors[:name].clear }
assert_empty person.errors
end
test "error access is indifferent" do
errors = ActiveModel::Errors.new(Person.new)
errors.add(:name, "omg")
@ -619,6 +628,15 @@ class ErrorsTest < ActiveModel::TestCase
)
end
test "messages delete (deprecated)" do
person = Person.new
person.validate!
assert_equal 1, person.errors.count
assert_deprecated { person.errors.messages.delete(:name) }
assert_empty person.errors
end
test "group_by_attribute" do
person = Person.new
error = person.errors.add(:name, :invalid, message: "is bad")