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

Ticket #8003: add_unless_conditional_to_validations.diff

File add_unless_conditional_to_validations.diff, 15.1 kB (added by monki, 2 years ago)

changes to ActiveRecord validation lib code and tests

  • activerecord/test/validations_test.rb

    old new  
    979979    assert_equal "This string contains 'single' and \"double\" quotes", r.errors.on(:topic).last 
    980980  end 
    981981 
    982   def test_conditional_validation_using_method_true 
     982  def test_if_validation_using_method_true 
    983983    # When the method returns true 
    984984    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true ) 
    985985    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    988988    assert_equal "hoo 5", t.errors["title"] 
    989989  end 
    990990 
    991   def test_conditional_validation_using_method_false 
     991  def test_unless_validation_using_method_true 
     992    # When the method returns true 
     993    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true ) 
     994    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     995    assert t.valid? 
     996    assert !t.errors.on(:title) 
     997  end 
     998 
     999  def test_if_validation_using_method_false 
    9921000    # When the method returns false 
    9931001    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not ) 
    9941002    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    9961004    assert !t.errors.on(:title) 
    9971005  end 
    9981006 
    999   def test_conditional_validation_using_string_true 
     1007  def test_unless_validation_using_method_false 
     1008    # When the method returns false 
     1009    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => :condition_is_true_but_its_not ) 
     1010    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1011    assert !t.valid? 
     1012    assert t.errors.on(:title) 
     1013    assert_equal "hoo 5", t.errors["title"] 
     1014  end 
     1015 
     1016  def test_if_validation_using_string_true 
    10001017    # When the evaluated string returns true 
    10011018    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" ) 
    10021019    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    10051022    assert_equal "hoo 5", t.errors["title"] 
    10061023  end 
    10071024 
    1008   def test_conditional_validation_using_string_false 
     1025  def test_unless_validation_using_string_true 
     1026    # When the evaluated string returns true 
     1027    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "a = 1; a == 1" ) 
     1028    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1029    assert t.valid? 
     1030    assert !t.errors.on(:title) 
     1031  end 
     1032 
     1033  def test_if_validation_using_string_false 
    10091034    # When the evaluated string returns false 
    10101035    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false") 
    10111036    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     
    10131038    assert !t.errors.on(:title) 
    10141039  end 
    10151040 
    1016   def test_conditional_validation_using_block_true 
     1041  def test_unless_validation_using_string_false 
     1042    # When the evaluated string returns false 
     1043    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :unless => "false") 
     1044    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1045    assert !t.valid? 
     1046    assert t.errors.on(:title) 
     1047    assert_equal "hoo 5", t.errors["title"] 
     1048  end 
     1049 
     1050  def test_if_validation_using_block_true 
    10171051    # When the block returns true 
    10181052    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
    10191053      :if => Proc.new { |r| r.content.size > 4 } ) 
     
    10231057    assert_equal "hoo 5", t.errors["title"] 
    10241058  end 
    10251059 
    1026   def test_conditional_validation_using_block_false 
     1060  def test_unless_validation_using_block_true 
     1061    # When the block returns true 
     1062    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     1063      :unless => Proc.new { |r| r.content.size > 4 } ) 
     1064    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1065    assert t.valid? 
     1066    assert !t.errors.on(:title) 
     1067  end 
     1068 
     1069  def test_if_validation_using_block_false 
    10271070    # When the block returns false 
    10281071    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
    10291072      :if => Proc.new { |r| r.title != "uhohuhoh"} ) 
     
    10321075    assert !t.errors.on(:title) 
    10331076  end 
    10341077 
     1078  def test_unless_validation_using_block_false 
     1079    # When the block returns false 
     1080    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", 
     1081      :unless => Proc.new { |r| r.title != "uhohuhoh"} ) 
     1082    t = Topic.create("title" => "uhohuhoh", "content" => "whatever") 
     1083    assert !t.valid? 
     1084    assert t.errors.on(:title) 
     1085    assert_equal "hoo 5", t.errors["title"] 
     1086  end 
     1087 
    10351088  def test_validates_associated_missing 
    10361089    Reply.validates_presence_of(:topic) 
    10371090    r = Reply.create("title" => "A reply", "content" => "with content!") 
  • activerecord/lib/active_record/validations.rb

    old new  
    351351      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    352352      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    353353      # method, proc or string should return or evaluate to a true or false value. 
     354      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     355      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     356      # method, proc or string should return or evaluate to a true or false value.       
    354357      def validates_each(*attrs) 
    355358        options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {} 
    356359        attrs   = attrs.flatten 
    357360 
    358361        # Declare the validation. 
    359362        send(validation_method(options[:on] || :save)) do |record| 
    360           # Don't validate when there is an :if condition and that condition is false 
    361           unless options[:if] && !evaluate_condition(options[:if], record
     363          # 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 
     364          unless (options[:if] && !evaluate_condition(options[:if], record)) || (options[:unless] && evaluate_condition(options[:unless], record)
    362365            attrs.each do |attr| 
    363366              value = record.send(attr) 
    364367              next if value.nil? && options[:allow_nil] 
     
    390393      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    391394      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    392395      # method, proc or string should return or evaluate to a true or false value. 
     396      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     397      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     398      # method, proc or string should return or evaluate to a true or false value.       
    393399      def validates_confirmation_of(*attr_names) 
    394400        configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save } 
    395401        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    419425      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    420426      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    421427      # method, proc or string should return or evaluate to a true or false value. 
     428      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     429      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     430      # method, proc or string should return or evaluate to a true or false value.       
    422431      def validates_acceptance_of(*attr_names) 
    423432        configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" } 
    424433        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    448457      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    449458      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    450459      # method, proc or string should return or evaluate to a true or false value. 
     460      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     461      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     462      # method, proc or string should return or evaluate to a true or false value. 
    451463      # 
    452464      # === Warning 
    453465      # Validate the presence of the foreign key, not the instance variable itself. 
     
    468480        # while errors.add_on_empty can 
    469481        attr_names.each do |attr_name| 
    470482          send(validation_method(configuration[:on])) do |record| 
    471             unless configuration[:if] and not evaluate_condition(configuration[:if], record
     483            unless (configuration[:if] && !evaluate_condition(configuration[:if], record)) || (configuration[:unless] && evaluate_condition(configuraton[:unless], record)
    472484              record.errors.add_on_blank(attr_name,configuration[:message]) 
    473485            end 
    474486          end 
     
    502514      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    503515      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    504516      # method, proc or string should return or evaluate to a true or false value. 
     517      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     518      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     519      # method, proc or string should return or evaluate to a true or false value.       
    505520      def validates_length_of(*attrs) 
    506521        # Merge given options with defaults. 
    507522        options = { 
     
    587602      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    588603      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    589604      # method, proc or string should return or evaluate to a true or false value. 
     605      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     606      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     607      # method, proc or string should return or evaluate to a true or false value. 
    590608      def validates_uniqueness_of(*attr_names) 
    591609        configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken], :case_sensitive => true } 
    592610        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    635653      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    636654      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    637655      # method, proc or string should return or evaluate to a true or false value. 
     656      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     657      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     658      # method, proc or string should return or evaluate to a true or false value. 
    638659      def validates_format_of(*attr_names) 
    639660        configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil } 
    640661        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    660681      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    661682      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    662683      # method, proc or string should return or evaluate to a true or false value. 
     684      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     685      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     686      # method, proc or string should return or evaluate to a true or false value. 
    663687      def validates_inclusion_of(*attr_names) 
    664688        configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save } 
    665689        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    687711      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    688712      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    689713      # method, proc or string should return or evaluate to a true or false value. 
     714      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     715      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     716      # method, proc or string should return or evaluate to a true or false value. 
    690717      def validates_exclusion_of(*attr_names) 
    691718        configuration = { :message => ActiveRecord::Errors.default_error_messages[:exclusion], :on => :save } 
    692719        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    727754      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    728755      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    729756      # method, proc or string should return or evaluate to a true or false value. 
     757      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     758      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     759      # method, proc or string should return or evaluate to a true or false value. 
    730760      def validates_associated(*attr_names) 
    731761        configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save } 
    732762        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) 
     
    753783      # * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should 
    754784      # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }).  The 
    755785      # method, proc or string should return or evaluate to a true or false value. 
     786      # * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should 
     787      # not occur (e.g. :if => :disallow_validation, or :if => Proc.new { |user| user.signup_step <= 2 }).  The 
     788      # method, proc or string should return or evaluate to a true or false value. 
    756789      def validates_numericality_of(*attr_names) 
    757790        configuration = { :message => ActiveRecord::Errors.default_error_messages[:not_a_number], :on => :save, 
    758791                           :only_integer => false, :allow_nil => false }