New #added? method on ActiveModel::Errors

The #added? method makes it possible to check if a specific error has been added, using the same parameters as for #add.
This commit is contained in:
Martin Svalin 2011-10-19 18:47:28 +02:00
parent 89a164ab9b
commit c9ca86c29d
3 changed files with 68 additions and 7 deletions

@ -1,3 +1,5 @@
* Added ActiveModel::Errors#added? to check if a specific error has been added [Martin Svalin]
* Add ability to define strict validation(with :strict => true option) that always raises exception when fails [Bogdan Gusiev]
* Deprecate "Model.model_name.partial_path" in favor of "model.to_partial_path" [Grant Hutchins, Peter Jaros]

@ -213,13 +213,7 @@ def to_hash
# If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_error+).
# If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error.
def add(attribute, message = nil, options = {})
message ||= :invalid
if message.is_a?(Symbol)
message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS))
elsif message.is_a?(Proc)
message = message.call
end
message = normalize_message(attribute, message, options)
if options[:strict]
raise ActiveModel::StrictValidationFailed, message
end
@ -244,6 +238,15 @@ def add_on_blank(attributes, options = {})
end
end
# Returns true if an error on the attribute with the given message is present, false otherwise.
# +message+ is treated the same as for +add+.
# p.errors.add :name, :blank
# p.errors.added? :name, :blank # => true
def added?(attribute, message = nil, options = {})
message = normalize_message(attribute, message, options)
self[attribute].include? message
end
# Returns all the full error messages in an array.
#
# class Company
@ -329,6 +332,19 @@ def generate_message(attribute, type = :invalid, options = {})
I18n.translate(key, options)
end
private
def normalize_message(attribute, message, options)
message ||= :invalid
if message.is_a?(Symbol)
generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS))
elsif message.is_a?(Proc)
message.call
else
message
end
end
end
class StrictValidationFailed < StandardError

@ -80,6 +80,49 @@ def test_has_key?
assert_equal ["can not be blank"], person.errors[:name]
end
test "added? should be true if that error was added" do
person = Person.new
person.errors.add(:name, "can not be blank")
assert person.errors.added?(:name, "can not be blank")
end
test "added? should handle when message is a symbol" do
person = Person.new
person.errors.add(:name, :blank)
assert person.errors.added?(:name, :blank)
end
test "added? should handle when message is a proc" do
person = Person.new
message = Proc.new { "can not be blank" }
person.errors.add(:name, message)
assert person.errors.added?(:name, message)
end
test "added? should default message to :invalid" do
person = Person.new
person.errors.add(:name, :invalid)
assert person.errors.added?(:name)
end
test "added? should be true when several errors are present, and we ask for one of them" do
person = Person.new
person.errors.add(:name, "can not be blank")
person.errors.add(:name, "is invalid")
assert person.errors.added?(:name, "can not be blank")
end
test "added? should be false if no errors are present" do
person = Person.new
assert !person.errors.added?(:name)
end
test "added? should be false when an error is present, but we check for another error" do
person = Person.new
person.errors.add(:name, "is invalid")
assert !person.errors.added?(:name, "can not be blank")
end
test 'should respond to size' do
person = Person.new
person.errors.add(:name, "can not be blank")