diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 9220eae..3c2c1b7 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -852,8 +852,10 @@ module ActiveRecord # * :unless - 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. + # * :case_sensitive - Looks for an exact match. If true, enumerable object specified by :in should + # contain only lowercase values (default is +true+). def validates_exclusion_of(*attr_names) - configuration = { :on => :save } + configuration = { :on => :save, :case_sensitive => true } configuration.update(attr_names.extract_options!) enum = configuration[:in] || configuration[:within] @@ -861,7 +863,7 @@ module ActiveRecord raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?(:include?) validates_each(attr_names, configuration) do |record, attr_name, value| - if enum.include?(value) + if enum.include?(value) || (!configuration[:case_sensitive] && value.respond_to?(:downcase) && enum.include?(value.downcase)) record.errors.add(attr_name, :exclusion, :default => configuration[:message], :value => value) end end diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index c049659..1bf14bd 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -708,6 +708,14 @@ class ValidationsTest < ActiveRecord::TestCase assert_equal "option monkey is restricted", t.errors["title"] end + def test_validates_exclusion_of_with_case_sensitive + Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :case_sensitive => false ) + + assert Topic.create("title" => "something", "content" => "abc").valid? + assert !Topic.create("title" => "monkey", "content" => "abc").valid? + assert !Topic.create("title" => "monKey", "content" => "abc").valid? + end + def test_validates_length_of_using_minimum Topic.validates_length_of :title, :minimum => 5