Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add `ActiveModel::Validations::AbsenceValidator`, a validator to chec…

…k the absence of attributes.

Add `ActiveModel::Errors#add_on_present` method. Adds error messages to present attributes.
  • Loading branch information...
commit d72a07f1d1478db9daed847eadb35bfd840674f6 1 parent c298ee4
@robotex82 robotex82 authored steveklabnik committed
View
19 activemodel/CHANGELOG.md
@@ -1,4 +1,23 @@
## Rails 4.0.0 (unreleased) ##
+* Add `ActiveModel::Validations::AbsenceValidator`, a validator to check the
+ absence of attributes.
+
+ class Person < ActiveRecord::Base
+ validates_absence_of :first_name
+ end
+
+ person = Person.new
+ person.first_name = "John"
+ person.valid?
+ => false
+ # first_name must be blank
+
+ * Roberto Vasquez Angel*
+
+* Added `ActiveModel::Errors#add_on_present` method. Adds error messages to
+ present attributes.
+
+ *Roberto Vasquez Angel*
* `[attribute]_changed?` now returns `false` after a call to `reset_[attribute]!`
View
13 activemodel/lib/active_model/errors.rb
@@ -328,6 +328,19 @@ def add_on_blank(attributes, options = {})
end
end
+ # Will add an error message to each of the attributes in +attributes+ that
+ # is present (using Object#present?).
+ #
+ # person.errors.add_on_present(:name)
+ # person.errors.messages
+ # # => { :name => ["must be blank"] }
+ def add_on_present(attributes, options = {})
+ Array(attributes).flatten.each do |attribute|
+ value = @base.send(:read_attribute_for_validation, attribute)
+ add(attribute, :not_blank, options) if value.present?
+ end
+ end

I think @josevalim had some concerns about adding more of these to AMo.

@steveklabnik Collaborator
@josevalim Owner

Yeah, I don't see the need for such helpers. We don't have add_on_unnaceptable, add_on_non_uniq and as such.

@steveklabnik Collaborator

I don't think it needs to be reverted, it's just that this logic could be inside the validator itself instead of adding another api in AMo::Errors I think.

@rafaelfranca Owner

Done b437053

@steveklabnik Collaborator

Thank you! I've been training all week, so I've been slow on the Rails uptake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
# Returns +true+ if an error on the attribute with the given message is
# present, +false+ otherwise. +message+ is treated the same as for +add+.
#
View
1  activemodel/lib/active_model/locale/en.yml
@@ -13,6 +13,7 @@ en:
accepted: "must be accepted"
empty: "can't be empty"
blank: "can't be blank"
+ not_blank: "must be blank"

Should we use present?

@steveklabnik Collaborator

:+1:

:thumbsup: x2

@rafaelfranca Owner

Done ac6941f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
too_long: "is too long (maximum is %{count} characters)"
too_short: "is too short (minimum is %{count} characters)"
wrong_length: "is the wrong length (should be %{count} characters)"
View
31 activemodel/lib/active_model/validations/absence.rb
@@ -0,0 +1,31 @@
+module ActiveModel
+ module Validations
+ # == Active Model Absence Validator
+ class AbsenceValidator < EachValidator #:nodoc:
+ def validate(record)
+ record.errors.add_on_present(attributes, options)
+ end
+ end
+
+ module HelperMethods
+ # Validates that the specified attributes are blank (as defined by
+ # Object#blank?). Happens by default on save.
+ #
+ # class Person < ActiveRecord::Base
+ # validates_absence_of :first_name
+ # end
+ #
+ # The first_name attribute must be in the object and it must be blank.
+ #
+ # Configuration options:
+ # * <tt>:message</tt> - A custom error message (default is: "must be blank").
+ #
+ # There is also a list of default options supported by every validator:
+ # +:if+, +:unless+, +:on+ and +:strict+.
+ # See <tt>ActiveModel::Validation#validates</tt> for more information
+ def validates_absence_of(*attr_names)
+ validates_with AbsenceValidator, _merge_attributes(attr_names)
+ end
+ end
+ end
+end
View
67 activemodel/test/cases/validations/absence_validation_test.rb
@@ -0,0 +1,67 @@
+# encoding: utf-8
+require 'cases/helper'
+require 'models/topic'
+require 'models/person'
+require 'models/custom_reader'
+
+class AbsenceValidationTest < ActiveModel::TestCase
+ teardown do
+ Topic.reset_callbacks(:validate)
+ Person.reset_callbacks(:validate)
+ CustomReader.reset_callbacks(:validate)
+ end
+
+ def test_validate_absences
+ Topic.validates_absence_of(:title, :content)
+ t = Topic.new
+ t.title = "foo"
+ t.content = "bar"
+ assert t.invalid?
+ assert_equal ["must be blank"], t.errors[:title]
+ assert_equal ["must be blank"], t.errors[:content]
+ t.title = ""
+ t.content = "something"
+ assert t.invalid?
+ assert_equal ["must be blank"], t.errors[:content]
+ t.content = ""
+ assert t.valid?
+ end
+
+ def test_accepts_array_arguments
+ Topic.validates_absence_of %w(title content)
+ t = Topic.new
+ t.title = "foo"
+ t.content = "bar"
+ assert t.invalid?
+ assert_equal ["must be blank"], t.errors[:title]
+ assert_equal ["must be blank"], t.errors[:content]
+ end
+
+ def test_validates_acceptance_of_with_custom_error_using_quotes
+ Person.validates_absence_of :karma, message: "This string contains 'single' and \"double\" quotes"
+ p = Person.new
+ p.karma = "good"
+ assert p.invalid?
+ assert_equal "This string contains 'single' and \"double\" quotes", p.errors[:karma].last
+ end
+
+ def test_validates_absence_of_for_ruby_class
+ Person.validates_absence_of :karma
+ p = Person.new
+ p.karma = "good"
+ assert p.invalid?
+ assert_equal ["must be blank"], p.errors[:karma]
+ p.karma = nil
+ assert p.valid?
+ end
+
+ def test_validates_absence_of_for_ruby_class_with_custom_reader
+ CustomReader.validates_absence_of :karma
+ p = CustomReader.new
+ p[:karma] = "excellent"
+ assert p.invalid?
+ assert_equal ["must be blank"], p.errors[:karma]
+ p[:karma] = ""
+ assert p.valid?
+ end
+end

1 comment on commit d72a07f

@carlosantoniodasilva

I think @josevalim had some concerns about adding more of these to AMo.

@steveklabnik
Collaborator

Oh, for future reference, this was introduced in #7155.

@josevalim

Yeah, I don't see the need for such helpers. We don't have add_on_unnaceptable, add_on_non_uniq and as such.

@steveklabnik
@carlosantoniodasilva

I don't think it needs to be reverted, it's just that this logic could be inside the validator itself instead of adding another api in AMo::Errors I think.

@steveklabnik

Thank you! I've been training all week, so I've been slow on the Rails uptake.

Please sign in to comment.
Something went wrong with that request. Please try again.