mirror of https://github.com/rails/rails
Allow validates to map some types to specific options. So now you can do:
validates :email, :presence => true, :format => /@/ validates :genre, :inclusion => %w(m f) validates :password, :length => 6..20
This commit is contained in:
parent
fa14d6d51e
commit
7045c4c279
|
@ -10,9 +10,10 @@ module ActiveModel
|
|||
end
|
||||
|
||||
def check_validity!
|
||||
options.slice(*CHECKS.keys) do |option, value|
|
||||
next if [:odd, :even].include?(option)
|
||||
raise ArgumentError, ":#{option} must be a number, a symbol or a proc" unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
|
||||
keys = CHECKS.keys - [:odd, :event]
|
||||
options.slice(*keys) do |option, value|
|
||||
next if value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
|
||||
raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ module ActiveModel
|
|||
# custom validator classes in their place such as PresenceValidator.
|
||||
#
|
||||
# Examples of using the default rails validators:
|
||||
#
|
||||
# validates :terms, :acceptance => true
|
||||
# validates :password, :confirmation => true
|
||||
# validates :username, :exclusion => { :in => %w(admin superuser) }
|
||||
|
@ -19,6 +20,7 @@ module ActiveModel
|
|||
#
|
||||
# The power of the +validates+ method comes when using cusom validators
|
||||
# and default validators in one call for a given attribute e.g.
|
||||
#
|
||||
# class EmailValidator < ActiveModel::EachValidator
|
||||
# def validate_each(record, attribute, value)
|
||||
# record.errors[attribute] << (options[:message] || "is not an email") unless
|
||||
|
@ -31,29 +33,32 @@ module ActiveModel
|
|||
# attr_accessor :name, :email
|
||||
#
|
||||
# validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 100 }
|
||||
# validates :email, :presence => true, :format => { :with => /@/ }
|
||||
# validates :email, :presence => true, :email => true
|
||||
# end
|
||||
#
|
||||
# Validator classes my also exist within the class being validated
|
||||
# allowing custom modules of validators to be included as needed e.g.
|
||||
#
|
||||
# module MyValidators
|
||||
#
|
||||
# class Film
|
||||
# include ActiveModel::Validations
|
||||
#
|
||||
# class TitleValidator < ActiveModel::EachValidator
|
||||
# def validate_each(record, attribute, value)
|
||||
# record.errors[attribute] << "must start with 'the'" unless =~ /^the/i
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# validates :name, :title => true
|
||||
# end
|
||||
#
|
||||
# class Film
|
||||
# include ActiveModel::Validations
|
||||
# include MyValidators
|
||||
#
|
||||
# validates :name, :title => true
|
||||
# end
|
||||
# The validators hash can also handle regular expressions, ranges and arrays:
|
||||
#
|
||||
# The options :if, :unless, :on, :allow_blank and :allow_nil can be given to one specific
|
||||
# validator:
|
||||
# validates :email, :format => /@/
|
||||
# validates :genre, :inclusion => %w(mail female)
|
||||
# validates :password, :length => 6..20
|
||||
#
|
||||
# Finally, the options :if, :unless, :on, :allow_blank and :allow_nil can be given
|
||||
# to one specific validator:
|
||||
#
|
||||
# validates :password, :presence => { :if => :password_required? }, :confirmation => true
|
||||
#
|
||||
|
@ -78,7 +83,22 @@ module ActiveModel
|
|||
raise ArgumentError, "Unknown validator: '#{key}'"
|
||||
end
|
||||
|
||||
validates_with(validator, defaults.merge(options == true ? {} : options))
|
||||
validates_with(validator, defaults.merge(_parse_validates_options(options)))
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def _parse_validates_options(options) #:nodoc:
|
||||
case options
|
||||
when TrueClass
|
||||
{}
|
||||
when Hash
|
||||
options
|
||||
when Regexp
|
||||
{ :with => options }
|
||||
when Range, Array
|
||||
{ :in => options }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,43 +10,42 @@ class ValidatesTest < ActiveModel::TestCase
|
|||
|
||||
def reset_callbacks
|
||||
Person.reset_callbacks(:validate)
|
||||
PersonWithValidator.reset_callbacks(:validate)
|
||||
end
|
||||
|
||||
def test_validates_with_built_in_validation
|
||||
Person.validates :title, :numericality => true
|
||||
person = Person.new
|
||||
person.valid?
|
||||
assert person.errors[:title].include?('is not a number')
|
||||
assert_equal ['is not a number'], person.errors[:title]
|
||||
end
|
||||
|
||||
def test_validates_with_built_in_validation_and_options
|
||||
Person.validates :title, :numericality => { :message => 'my custom message' }
|
||||
Person.validates :salary, :numericality => { :message => 'my custom message' }
|
||||
person = Person.new
|
||||
person.valid?
|
||||
assert person.errors[:title].include?('my custom message')
|
||||
assert_equal ['my custom message'], person.errors[:salary]
|
||||
end
|
||||
|
||||
def test_validates_with_validator_class
|
||||
Person.validates :karma, :email => true
|
||||
person = Person.new
|
||||
person.valid?
|
||||
assert person.errors[:karma].include?('is not an email')
|
||||
assert_equal ['is not an email'], person.errors[:karma]
|
||||
end
|
||||
|
||||
def test_validates_with_if_as_local_conditions
|
||||
Person.validates :karma, :presence => true, :email => { :unless => :condition_is_true }
|
||||
person = Person.new
|
||||
person.valid?
|
||||
assert !person.errors[:karma].include?('is not an email')
|
||||
assert person.errors[:karma].include?('can\'t be blank')
|
||||
assert_equal ["can't be blank"], person.errors[:karma]
|
||||
end
|
||||
|
||||
def test_validates_with_if_as_shared_conditions
|
||||
Person.validates :karma, :presence => true, :email => true, :if => :condition_is_true
|
||||
person = Person.new
|
||||
person.valid?
|
||||
assert person.errors[:karma].include?('is not an email')
|
||||
assert person.errors[:karma].include?('can\'t be blank')
|
||||
assert ["can't be blank", "is not an email"], person.errors[:karma].sort
|
||||
end
|
||||
|
||||
def test_validates_with_unless_shared_conditions
|
||||
|
@ -61,11 +60,38 @@ class ValidatesTest < ActiveModel::TestCase
|
|||
assert person.valid?
|
||||
end
|
||||
|
||||
def test_validates_with_regexp
|
||||
Person.validates :karma, :format => /positive|negative/
|
||||
person = Person.new
|
||||
assert person.invalid?
|
||||
assert_equal ['is invalid'], person.errors[:karma]
|
||||
person.karma = "positive"
|
||||
assert person.valid?
|
||||
end
|
||||
|
||||
def test_validates_with_array
|
||||
Person.validates :genre, :inclusion => %w(m f)
|
||||
person = Person.new
|
||||
assert person.invalid?
|
||||
assert_equal ['is not included in the list'], person.errors[:genre]
|
||||
person.genre = "m"
|
||||
assert person.valid?
|
||||
end
|
||||
|
||||
def test_validates_with_range
|
||||
Person.validates :password, :length => 6..20
|
||||
person = Person.new
|
||||
assert person.invalid?
|
||||
assert_equal ['is too short (minimum is 6 characters)'], person.errors[:password]
|
||||
person.password = '123456'
|
||||
assert person.valid?
|
||||
end
|
||||
|
||||
def test_validates_with_validator_class_and_options
|
||||
Person.validates :karma, :email => { :message => 'my custom message' }
|
||||
person = Person.new
|
||||
person.valid?
|
||||
assert person.errors[:karma].include?('my custom message')
|
||||
assert_equal ['my custom message'], person.errors[:karma]
|
||||
end
|
||||
|
||||
def test_validates_with_unknown_validator
|
||||
|
@ -76,13 +102,13 @@ class ValidatesTest < ActiveModel::TestCase
|
|||
PersonWithValidator.validates :title, :presence => true
|
||||
person = PersonWithValidator.new
|
||||
person.valid?
|
||||
assert person.errors[:title].include?('Local validator')
|
||||
assert_equal ['Local validator'], person.errors[:title]
|
||||
end
|
||||
|
||||
def test_validates_with_included_validator_and_options
|
||||
PersonWithValidator.validates :title, :presence => { :custom => ' please' }
|
||||
person = PersonWithValidator.new
|
||||
person.valid?
|
||||
assert person.errors[:title].include?('Local validator please')
|
||||
assert_equal ['Local validator please'], person.errors[:title]
|
||||
end
|
||||
end
|
|
@ -2,7 +2,7 @@ class Person
|
|||
include ActiveModel::Validations
|
||||
extend ActiveModel::Translation
|
||||
|
||||
attr_accessor :title, :karma, :salary
|
||||
attr_accessor :title, :karma, :salary, :genre, :password
|
||||
|
||||
def condition_is_true
|
||||
true
|
||||
|
|
Loading…
Reference in New Issue