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

Ticket #8003: add_unless_conditional_to_validations.3.diff

File add_unless_conditional_to_validations.3.diff, 15.2 kB (added by kampers, 1 year ago)

New revision of patch against [7200] with clarification in docs

  • activerecord/test/validations_test.rb

    old new  
    988988    assert_equal "This string contains 'single' and \"double\" quotes", r.errors.on(:topic).last 
    989989  end 
    990990 
    991   def test_conditional_validation_using_method_true 
     991  def test_if_validation_using_method_true 
    992992    # When the method returns true 
    993993    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true ) 
    994994    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    997997    assert_equal "hoo 5", t.errors["title"] 
    998998  end 
    999999 
    1000   def test_conditional_validation_using_method_false 
     1000  def test_unless_validation_using_method_true 
     1001    # When the method returns true 
     1002    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true ) 
     1003    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1004    assert t.valid? 
     1005    assert !t.errors.on(:title) 
     1006  end 
     1007 
     1008  def test_if_validation_using_method_false 
    10011009    # When the method returns false 
    10021010    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not ) 
    10031011    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    10051013    assert !t.errors.on(:title) 
    10061014  end 
    10071015 
    1008   def test_conditional_validation_using_string_true 
     1016  def test_unless_validation_using_method_false 
     1017    # When the method returns false 
     1018    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true_but_its_not ) 
     1019    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1020    assert !t.valid? 
     1021    assert t.errors.on(:title) 
     1022    assert_equal "hoo 5", t.errors["title"] 
     1023  end 
     1024 
     1025  def test_if_validation_using_string_true 
    10091026    # When the evaluated string returns true 
    10101027    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" ) 
    10111028    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    10141031    assert_equal "hoo 5", t.errors["title"] 
    10151032  end 
    10161033 
    1017   def test_conditional_validation_using_string_false 
     1034  def test_unless_validation_using_string_true 
     1035    # When the evaluated string returns true 
     1036    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "a = 1; a == 1" ) 
     1037    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1038    assert t.valid? 
     1039    assert !t.errors.on(:title) 
     1040  end 
     1041 
     1042  def test_if_validation_using_string_false 
    10181043    # When the evaluated string returns false 
    10191044    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false") 
    10201045    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    10221047    assert !t.errors.on(:title) 
    10231048  end 
    10241049 
    1025   def test_conditional_validation_using_block_true 
     1050  def test_unless_validation_using_string_false 
     1051    # When the evaluated string returns false 
     1052    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "false") 
     1053    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1054    assert !t.valid? 
     1055    assert t.errors.on(:title) 
     1056    assert_equal "hoo 5", t.errors["title"] 
     1057  end 
     1058 
     1059  def test_if_validation_using_block_true 
    10261060    # When the block returns true 
    10271061    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
    10281062      :if => Proc.new { |r| r.content.size > 4 } ) 
     
    10321066    assert_equal "hoo 5", t.errors["title"] 
    10331067  end 
    10341068 
    1035   def test_conditional_validation_using_block_false 
     1069  def test_unless_validation_using_block_true 
     1070    # When the block returns true 
     1071    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     1072      :unless => Proc.new { |r| r.content.size > 4 } ) 
     1073    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1074    assert t.valid? 
     1075    assert !t.errors.on(:title) 
     1076  end 
     1077 
     1078  def test_if_validation_using_block_false 
    10361079    # When the block returns false 
    10371080    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
    10381081      :if => Proc.new { |r| r.title != "uhohuhoh"} ) 
     
    10411084    assert !t.errors.on(:title) 
    10421085  end 
    10431086 
     1087  def test_unless_validation_using_block_false 
     1088    # When the block returns false 
     1089    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     1090      :unless => Proc.new { |r| r.title != "uhohuhoh"} ) 
     1091    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1092    assert !t.valid? 
     1093    assert t.errors.on(:title) 
     1094    assert_equal "hoo 5", t.errors["title"] 
     1095  end 
     1096 
    10441097  def test_validates_associated_missing 
    10451098    Reply.validates_presence_of(:topic) 
    10461099    r = Reply.create("title" => "A reply", "content" => "with content!") 
  • activerecord/lib/active_record/validations.rb

    old new  
    362362      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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 : {} 
    367370        attrs   = attrs.flatten 
    368371 
    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) 
    375378              next if value.nil? && options[:allow_nil] 
     
    401404      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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 } 
    406412        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    431437      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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" } 
    436445        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    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 
    462471      # 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 
     474      # method, proc or string should return or evaluate to a true or false value. 
    463475      # 
    464476      # === Warning 
    465477      # Validate the presence of the foreign key, not the instance variable itself. 
     
    480492        # while errors.add_on_empty can 
    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 
    486498          end 
     
    514526      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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. 
    519534        options = { 
     
    599614      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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 } 
    604622        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    647665      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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 } 
    652673        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    672693      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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 } 
    677701        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    699723      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    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 } 
    704731        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    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 
    741768      # 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 
     771      # method, proc or string should return or evaluate to a true or false value. 
    742772      def validates_associated(*attr_names) 
    743773        configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save } 
    744774        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    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 
    774804      # 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 
     807      # method, proc or string should return or evaluate to a true or false value. 
    775808      def validates_numericality_of(*attr_names) 
    776809        configuration = { :on => :save, :only_integer => false, :allow_nil => false } 
    777810        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)