Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 7215

Show
Ignore:
Timestamp:
07/24/07 01:48:17 (1 year ago)
Author:
david
Message:

Added :unless clause to validations (closes #8003) [monki]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r7199 r7215  
    11*SVN* 
     2 
     3* Added :unless clause to validations #8003 [monki]. Example:  
     4 
     5    def using_open_id? 
     6      !identity_url.blank? 
     7    end 
     8 
     9    validates_presence_of :identity_url, :if => using_open_id? 
     10    validates_presence_of :username, :unless => using_open_id? 
     11    validates_presence_of :password, :unless => using_open_id? 
    212 
    313* Fix #count on a has_many :through association so that it recognizes the :uniq option.  Closes #8801 [lifofifo] 
  • trunk/activerecord/lib/active_record/validations.rb

    r7094 r7215  
    363363      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    364364      # method, proc or string should return or evaluate to a true or false value. 
     365      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     366      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     367      # method, proc or string should return or evaluate to a true or false value.       
    365368      def validates_each(*attrs) 
    366369        options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {} 
     
    369372        # Declare the validation. 
    370373        send(validation_method(options[:on] || :save)) do |record| 
    371           # Don't validate when there is an :if condition and that condition is false 
    372           unless options[:if] && !evaluate_condition(options[:if], record
     374          # 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 
     375          unless (options[:if] && !evaluate_condition(options[:if], record)) || (options[:unless] && evaluate_condition(options[:unless], record)
    373376            attrs.each do |attr| 
    374377              value = record.send(attr) 
     
    402405      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    403406      # method, proc or string should return or evaluate to a true or false value. 
     407      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     408      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     409      # method, proc or string should return or evaluate to a true or false value.       
    404410      def validates_confirmation_of(*attr_names) 
    405411        configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save } 
     
    432438      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    433439      # method, proc or string should return or evaluate to a true or false value. 
     440      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     441      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     442      # method, proc or string should return or evaluate to a true or false value.       
    434443      def validates_acceptance_of(*attr_names) 
    435444        configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" } 
     
    460469      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    461470      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
     471      # method, proc or string should return or evaluate to a true or false value. 
     472      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     473      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
    462474      # method, proc or string should return or evaluate to a true or false value. 
    463475      # 
     
    481493        attr_names.each do |attr_name| 
    482494          send(validation_method(configuration[:on])) do |record| 
    483             unless configuration[:if] and not evaluate_condition(configuration[:if], record
     495            unless (configuration[:if] && !evaluate_condition(configuration[:if], record)) || (configuration[:unless] && evaluate_condition(configuration[:unless], record)
    484496              record.errors.add_on_blank(attr_name,configuration[:message]) 
    485497            end 
     
    515527      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    516528      # method, proc or string should return or evaluate to a true or false value. 
     529      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     530      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     531      # method, proc or string should return or evaluate to a true or false value.       
    517532      def validates_length_of(*attrs) 
    518533        # Merge given options with defaults. 
     
    600615      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    601616      # method, proc or string should return or evaluate to a true or false value. 
     617      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     618      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     619      # method, proc or string should return or evaluate to a true or false value. 
    602620      def validates_uniqueness_of(*attr_names) 
    603621        configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken], :case_sensitive => true } 
     
    648666      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    649667      # method, proc or string should return or evaluate to a true or false value. 
     668      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     669      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     670      # method, proc or string should return or evaluate to a true or false value. 
    650671      def validates_format_of(*attr_names) 
    651672        configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil } 
     
    673694      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    674695      # method, proc or string should return or evaluate to a true or false value. 
     696      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     697      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     698      # method, proc or string should return or evaluate to a true or false value. 
    675699      def validates_inclusion_of(*attr_names) 
    676700        configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save } 
     
    700724      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    701725      # method, proc or string should return or evaluate to a true or false value. 
     726      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     727      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
     728      # method, proc or string should return or evaluate to a true or false value. 
    702729      def validates_exclusion_of(*attr_names) 
    703730        configuration = { :message => ActiveRecord::Errors.default_error_messages[:exclusion], :on => :save } 
     
    739766      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    740767      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
     768      # method, proc or string should return or evaluate to a true or false value. 
     769      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     770      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
    741771      # method, proc or string should return or evaluate to a true or false value. 
    742772      def validates_associated(*attr_names) 
     
    772802      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    773803      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
     804      # method, proc or string should return or evaluate to a true or false value. 
     805      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     806      # not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }).  The 
    774807      # method, proc or string should return or evaluate to a true or false value. 
    775808      def validates_numericality_of(*attr_names) 
  • trunk/activerecord/test/validations_test.rb

    r7094 r7215  
    10011001  end 
    10021002 
    1003   def test_conditional_validation_using_method_true 
     1003  def test_if_validation_using_method_true 
    10041004    # When the method returns true 
    10051005    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true ) 
     
    10101010  end 
    10111011 
    1012   def test_conditional_validation_using_method_false 
     1012  def test_unless_validation_using_method_true 
     1013    # When the method returns true 
     1014    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true ) 
     1015    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1016    assert t.valid? 
     1017    assert !t.errors.on(:title) 
     1018  end 
     1019 
     1020  def test_if_validation_using_method_false 
    10131021    # When the method returns false 
    10141022    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not ) 
     
    10181026  end 
    10191027 
    1020   def test_conditional_validation_using_string_true 
     1028  def test_unless_validation_using_method_false 
     1029    # When the method returns false 
     1030    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true_but_its_not ) 
     1031    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1032    assert !t.valid? 
     1033    assert t.errors.on(:title) 
     1034    assert_equal "hoo 5", t.errors["title"] 
     1035  end 
     1036 
     1037  def test_if_validation_using_string_true 
    10211038    # When the evaluated string returns true 
    10221039    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" ) 
     
    10271044  end 
    10281045 
    1029   def test_conditional_validation_using_string_false 
     1046  def test_unless_validation_using_string_true 
     1047    # When the evaluated string returns true 
     1048    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "a = 1; a == 1" ) 
     1049    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1050    assert t.valid? 
     1051    assert !t.errors.on(:title) 
     1052  end 
     1053 
     1054  def test_if_validation_using_string_false 
    10301055    # When the evaluated string returns false 
    10311056    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false") 
     
    10351060  end 
    10361061 
    1037   def test_conditional_validation_using_block_true 
     1062  def test_unless_validation_using_string_false 
     1063    # When the evaluated string returns false 
     1064    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "false") 
     1065    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1066    assert !t.valid? 
     1067    assert t.errors.on(:title) 
     1068    assert_equal "hoo 5", t.errors["title"] 
     1069  end 
     1070 
     1071  def test_if_validation_using_block_true 
    10381072    # When the block returns true 
    10391073    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     
    10451079  end 
    10461080 
    1047   def test_conditional_validation_using_block_false 
     1081  def test_unless_validation_using_block_true 
     1082    # When the block returns true 
     1083    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     1084      :unless => Proc.new { |r| r.content.size > 4 } ) 
     1085    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1086    assert t.valid? 
     1087    assert !t.errors.on(:title) 
     1088  end 
     1089 
     1090  def test_if_validation_using_block_false 
    10481091    # When the block returns false 
    10491092    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     
    10521095    assert t.valid? 
    10531096    assert !t.errors.on(:title) 
     1097  end 
     1098 
     1099  def test_unless_validation_using_block_false 
     1100    # When the block returns false 
     1101    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     1102      :unless => Proc.new { |r| r.title != "uhohuhoh"} ) 
     1103    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1104    assert !t.valid? 
     1105    assert t.errors.on(:title) 
     1106    assert_equal "hoo 5", t.errors["title"] 
    10541107  end 
    10551108