mirror of
https://github.com/github/rails.git
synced 2026-02-13 23:55:16 -05:00
Added :unless clause to validations (closes #8003) [monki]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7215 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
*SVN*
|
||||
|
||||
* Added :unless clause to validations #8003 [monki]. Example:
|
||||
|
||||
def using_open_id?
|
||||
!identity_url.blank?
|
||||
end
|
||||
|
||||
validates_presence_of :identity_url, :if => using_open_id?
|
||||
validates_presence_of :username, :unless => using_open_id?
|
||||
validates_presence_of :password, :unless => using_open_id?
|
||||
|
||||
* Fix #count on a has_many :through association so that it recognizes the :uniq option. Closes #8801 [lifofifo]
|
||||
|
||||
* Fix and properly document/test count(column_name) usage. Closes #8999 [lifofifo]
|
||||
|
||||
@@ -362,14 +362,17 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_each(*attrs)
|
||||
options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {}
|
||||
attrs = attrs.flatten
|
||||
|
||||
# Declare the validation.
|
||||
send(validation_method(options[:on] || :save)) do |record|
|
||||
# Don't validate when there is an :if condition and that condition is false
|
||||
unless options[:if] && !evaluate_condition(options[:if], record)
|
||||
# Don't validate when there is an :if condition and that condition is false or there is an :unless condition and that condition is true
|
||||
unless (options[:if] && !evaluate_condition(options[:if], record)) || (options[:unless] && evaluate_condition(options[:unless], record))
|
||||
attrs.each do |attr|
|
||||
value = record.send(attr)
|
||||
next if value.nil? && options[:allow_nil]
|
||||
@@ -401,6 +404,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_confirmation_of(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -431,6 +437,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_acceptance_of(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -460,6 +469,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
#
|
||||
# === Warning
|
||||
# Validate the presence of the foreign key, not the instance variable itself.
|
||||
@@ -480,7 +492,7 @@ module ActiveRecord
|
||||
# while errors.add_on_empty can
|
||||
attr_names.each do |attr_name|
|
||||
send(validation_method(configuration[:on])) do |record|
|
||||
unless configuration[:if] and not evaluate_condition(configuration[:if], record)
|
||||
unless (configuration[:if] && !evaluate_condition(configuration[:if], record)) || (configuration[:unless] && evaluate_condition(configuration[:unless], record))
|
||||
record.errors.add_on_blank(attr_name,configuration[:message])
|
||||
end
|
||||
end
|
||||
@@ -514,6 +526,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_length_of(*attrs)
|
||||
# Merge given options with defaults.
|
||||
options = {
|
||||
@@ -599,6 +614,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_uniqueness_of(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken], :case_sensitive => true }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -647,6 +665,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_format_of(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -672,6 +693,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_inclusion_of(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -699,6 +723,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_exclusion_of(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:exclusion], :on => :save }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -739,6 +766,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_associated(*attr_names)
|
||||
configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
@@ -772,6 +802,9 @@ module ActiveRecord
|
||||
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_numericality_of(*attr_names)
|
||||
configuration = { :on => :save, :only_integer => false, :allow_nil => false }
|
||||
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
||||
|
||||
@@ -988,7 +988,7 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert_equal "This string contains 'single' and \"double\" quotes", r.errors.on(:topic).last
|
||||
end
|
||||
|
||||
def test_conditional_validation_using_method_true
|
||||
def test_if_validation_using_method_true
|
||||
# When the method returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
@@ -997,7 +997,15 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert_equal "hoo 5", t.errors["title"]
|
||||
end
|
||||
|
||||
def test_conditional_validation_using_method_false
|
||||
def test_unless_validation_using_method_true
|
||||
# When the method returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
end
|
||||
|
||||
def test_if_validation_using_method_false
|
||||
# When the method returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
@@ -1005,7 +1013,16 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert !t.errors.on(:title)
|
||||
end
|
||||
|
||||
def test_conditional_validation_using_string_true
|
||||
def test_unless_validation_using_method_false
|
||||
# When the method returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true_but_its_not )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
assert_equal "hoo 5", t.errors["title"]
|
||||
end
|
||||
|
||||
def test_if_validation_using_string_true
|
||||
# When the evaluated string returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
@@ -1014,7 +1031,15 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert_equal "hoo 5", t.errors["title"]
|
||||
end
|
||||
|
||||
def test_conditional_validation_using_string_false
|
||||
def test_unless_validation_using_string_true
|
||||
# When the evaluated string returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "a = 1; a == 1" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
end
|
||||
|
||||
def test_if_validation_using_string_false
|
||||
# When the evaluated string returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false")
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
@@ -1022,7 +1047,16 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert !t.errors.on(:title)
|
||||
end
|
||||
|
||||
def test_conditional_validation_using_block_true
|
||||
def test_unless_validation_using_string_false
|
||||
# When the evaluated string returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "false")
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
assert_equal "hoo 5", t.errors["title"]
|
||||
end
|
||||
|
||||
def test_if_validation_using_block_true
|
||||
# When the block returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
|
||||
:if => Proc.new { |r| r.content.size > 4 } )
|
||||
@@ -1032,7 +1066,16 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert_equal "hoo 5", t.errors["title"]
|
||||
end
|
||||
|
||||
def test_conditional_validation_using_block_false
|
||||
def test_unless_validation_using_block_true
|
||||
# When the block returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
|
||||
:unless => Proc.new { |r| r.content.size > 4 } )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
end
|
||||
|
||||
def test_if_validation_using_block_false
|
||||
# When the block returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
|
||||
:if => Proc.new { |r| r.title != "uhohuhoh"} )
|
||||
@@ -1041,6 +1084,16 @@ class ValidationsTest < Test::Unit::TestCase
|
||||
assert !t.errors.on(:title)
|
||||
end
|
||||
|
||||
def test_unless_validation_using_block_false
|
||||
# When the block returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d",
|
||||
:unless => Proc.new { |r| r.title != "uhohuhoh"} )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
assert_equal "hoo 5", t.errors["title"]
|
||||
end
|
||||
|
||||
def test_validates_associated_missing
|
||||
Reply.validates_presence_of(:topic)
|
||||
r = Reply.create("title" => "A reply", "content" => "with content!")
|
||||
|
||||
Reference in New Issue
Block a user