Permalink
Browse files

Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…

…s in validates.
  • Loading branch information...
1 parent 0a79eb7 commit 47a5fd4c4ba447c997c0a029adfa80d8b790b25a @josevalim josevalim committed Jan 7, 2010
@@ -121,9 +121,7 @@ def invalid?
# end
# end
#
- def read_attribute_for_validation(key)
- send(key)
- end
+ alias :read_attribute_for_validation :send
end
end
@@ -31,7 +31,7 @@ module ClassMethods
# attr_accessor :name, :email
#
# validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 100 }
- # validates :email, :presence => true, :email => true
+ # validates :email, :presence => true, :format => { :with => /@/ }
# end
#
# Validator classes my also exist within the class being validated
@@ -44,29 +44,41 @@ module ClassMethods
# end
# end
# end
- #
+ #
# class Film
# include ActiveModel::Validations
# include MyValidators
#
# validates :name, :title => true
# end
- #
+ #
+ # 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
+ #
+ # Or to all at the same time:
+ #
+ # validates :password, :presence => true, :confirmation => true, :if => :password_required?
+ #
def validates(*attributes)
- validations = attributes.extract_options!
+ defaults = attributes.extract_options!
+ validations = defaults.slice!(:if, :unless, :on, :allow_blank, :allow_nil)
raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
raise ArgumentError, "Attribute names must be symbols" if attributes.any?{ |attribute| !attribute.is_a?(Symbol) }
raise ArgumentError, "You need to supply at least one validation" if validations.empty?
-
+
+ defaults.merge!(:attributes => attributes)
+
validations.each do |key, options|
begin
validator = const_get("#{key.to_s.camelize}Validator")
rescue NameError
raise ArgumentError, "Unknown validator: '#{key}'"
end
- validates_with(validator, (options == true ? {} : options).merge(:attributes => attributes))
+ validates_with(validator, defaults.merge(options == true ? {} : options))
end
end
end
@@ -4,14 +4,21 @@
require 'models/person_with_validator'
require 'validators/email_validator'
-class ValidatesTest < ActiveRecord::TestCase
+class ValidatesTest < ActiveModel::TestCase
+ setup :reset_callbacks
+ teardown :reset_callbacks
+
+ def reset_callbacks
+ Person.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')
end
-
+
def test_validates_with_built_in_validation_and_options
Person.validates :title, :numericality => { :message => 'my custom message' }
person = Person.new
@@ -25,7 +32,35 @@ def test_validates_with_validator_class
person.valid?
assert person.errors[:karma].include?('is not an email')
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')
+ 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')
+ end
+
+ def test_validates_with_unless_shared_conditions
+ Person.validates :karma, :presence => true, :email => true, :unless => :condition_is_true
+ person = Person.new
+ assert person.valid?
+ end
+
+ def test_validates_with_allow_nil_shared_conditions
+ Person.validates :karma, :length => { :minimum => 20 }, :email => true, :allow_nil => true
+ person = Person.new
+ assert person.valid?
+ end
+
def test_validates_with_validator_class_and_options
Person.validates :karma, :email => { :message => 'my custom message' }
person = Person.new
@@ -3,6 +3,10 @@ class Person
extend ActiveModel::Translation
attr_accessor :title, :karma, :salary
+
+ def condition_is_true
+ true
+ end
end
class Child < Person

0 comments on commit 47a5fd4

Please sign in to comment.