@@ -627,17 +627,23 @@ def validates_uniqueness_of(*attr_names)
627
627
628
628
is_text_column = finder_class . columns_hash [ attr_name . to_s ] . text?
629
629
630
- if !value . nil? && is_text_column
631
- value = value . to_s
630
+ if value . nil?
631
+ comparison_operator = "IS ?"
632
+ else
633
+ comparison_operator = "#{ connection . case_sensitive_equality_operator } ?"
634
+
635
+ if is_text_column
636
+ value = value . to_s
637
+ end
632
638
end
633
639
640
+ sql_attribute = "#{ record . class . quoted_table_name } .#{ connection . quote_column_name ( attr_name ) } "
641
+
634
642
if value . nil? || ( configuration [ :case_sensitive ] || !is_text_column )
635
- condition_sql = "#{ record . class . quoted_table_name } . #{ attr_name } #{ attribute_condition ( value ) } "
643
+ condition_sql = "#{ sql_attribute } #{ comparison_operator } "
636
644
condition_params = [ value ]
637
645
else
638
- # sqlite has case sensitive SELECT query, while MySQL/Postgresql don't.
639
- # Hence, this is needed only for sqlite.
640
- condition_sql = "LOWER(#{ record . class . quoted_table_name } .#{ attr_name } ) #{ attribute_condition ( value ) } "
646
+ condition_sql = "LOWER(#{ sql_attribute } ) #{ comparison_operator } "
641
647
condition_params = [ value . downcase ]
642
648
end
643
649
@@ -654,28 +660,10 @@ def validates_uniqueness_of(*attr_names)
654
660
condition_params << record . send ( :id )
655
661
end
656
662
657
- results = finder_class . with_exclusive_scope do
658
- connection . select_all (
659
- construct_finder_sql (
660
- :select => "#{ connection . quote_column_name ( attr_name ) } " ,
661
- :from => "#{ finder_class . quoted_table_name } " ,
662
- :conditions => [ condition_sql , *condition_params ]
663
- )
664
- )
665
- end
666
-
667
- unless results . length . zero?
668
- found = true
669
-
670
- # As MySQL/Postgres don't have case sensitive SELECT queries, we try to find duplicate
671
- # column in ruby when case sensitive option
672
- if configuration [ :case_sensitive ] && finder_class . columns_hash [ attr_name . to_s ] . text?
673
- found = results . any? { |a | a [ attr_name . to_s ] == value . to_s }
674
- end
675
-
676
- if found
663
+ finder_class . with_exclusive_scope do
664
+ if finder_class . exists? ( [ condition_sql , *condition_params ] )
677
665
message = record . errors . generate_message ( attr_name , :taken , :default => configuration [ :message ] )
678
- record . errors . add ( attr_name , message )
666
+ record . errors . add ( attr_name , message )
679
667
end
680
668
end
681
669
end
0 commit comments