From e518a6ca32b506a76d68614312f803bcb55296da Mon Sep 17 00:00:00 2001 From: Phil Ross Date: Sun, 31 May 2009 15:13:10 +0100 Subject: [PATCH] Added a :case_sensitive => :db option to validates_uniqueness_of, which uses the database's case-sensitivity mode for comparisons. --- .../lib/active_record/validations/uniqueness.rb | 11 +++++++++-- .../validations/uniqueness_validation_test.rb | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index edec4e9..7ddab26 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -21,7 +21,9 @@ module ActiveRecord # Configuration options: # * :message - Specifies a custom error message (default is: "has already been taken"). # * :scope - One or more columns by which to limit the scope of the uniqueness constraint. - # * :case_sensitive - Looks for an exact match. Ignored by non-text columns (+true+ by default). + # * :case_sensitive - Set to true to look for an exact match or false to look for a + # case insensitive match. Can also be set to :db to use the databases case-sensitivity mode for the column. + # Ignored by non-text columns (+true+ by default). # * :allow_nil - If set to true, skips this validation if the attribute is +nil+ (default is +false+). # * :allow_blank - If set to true, skips this validation if the attribute is blank (default is +false+). # * :if - Specifies a method, proc or string to call to determine if the validation should @@ -118,7 +120,12 @@ module ActiveRecord if value.nil? comparison_operator = "IS ?" elsif column.text? - comparison_operator = "#{connection.case_sensitive_equality_operator} ?" + if configuration[:case_sensitive] == :db + comparison_operator = "= ?" + else + comparison_operator = "#{connection.case_sensitive_equality_operator} ?" + end + value = column.limit ? value.to_s[0, column.limit] : value.to_s else comparison_operator = "= ?" diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb index 961db51..7b8720e 100644 --- a/activerecord/test/cases/validations/uniqueness_validation_test.rb +++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb @@ -170,6 +170,24 @@ class UniquenessValidationTest < ActiveRecord::TestCase end end + def test_validate_db_case_sensitive_uniqueness + Topic.validates_uniqueness_of(:title, :case_sensitive => :db, :allow_nil => true) + + t = Topic.new(:title => "I'm unique!") + assert t.save, "Should save t" + + db_case_insensitive = Topic.find_all_by_id_and_title(t.id, "I'm UNIQUE!").any? + + t2 = Topic.new(:title => db_case_insensitive ? "I'm UNIQUE!" : "I'm unique!") + assert !t2.valid?, "Shouldn't be valid" + assert !t2.save, "Shouldn't save t2 as unique" + assert t2.errors[:title].any?, "Should be errors for title" + assert_equal ["has already been taken"], t2.errors[:title] + + t3 = Topic.new(:title => db_case_insensitive ? "I'm truly UNIQUE!" : "I'm UNIQUE!") + assert t3.save, "Should save t3" + end + def test_validate_case_sensitive_uniqueness Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true) -- 1.5.6.5