diff options
Diffstat (limited to 'activerecord/lib/active_record/validations/uniqueness.rb')
-rw-r--r-- | activerecord/lib/active_record/validations/uniqueness.rb | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 2e7b1d7206..f52f91e89c 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -16,9 +16,8 @@ module ActiveRecord value = map_enum_attribute(finder_class, attribute, value) relation = build_relation(finder_class, table, attribute, value) - relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted? + relation = relation.where.not(finder_class.primary_key => record.id) if record.persisted? relation = scope_relation(record, table, relation) - relation = finder_class.unscoped.where(relation) relation = relation.merge(options[:conditions]) if options[:conditions] if relation.exists? @@ -48,7 +47,7 @@ module ActiveRecord def build_relation(klass, table, attribute, value) #:nodoc: if reflection = klass._reflect_on_association(attribute) attribute = reflection.foreign_key - value = value.attributes[reflection.primary_key_column.name] unless value.nil? + value = value.attributes[reflection.klass.primary_key] unless value.nil? end attribute_name = attribute.to_s @@ -60,15 +59,21 @@ module ActiveRecord end column = klass.columns_hash[attribute_name] - value = klass.connection.type_cast(value, column) - value = value.to_s[0, column.limit] if value && column.limit && column.text? + value = klass.type_for_attribute(attribute_name).type_cast_for_database(value) + value = klass.connection.type_cast(value) + if value.is_a?(String) && column.limit + value = value.to_s[0, column.limit] + end + + value = Arel::Nodes::Quoted.new(value) - if !options[:case_sensitive] && value && column.text? + comparison = if !options[:case_sensitive] && value && column.text? # will use SQL LOWER function before comparison, unless it detects a case insensitive collation klass.connection.case_insensitive_comparison(table, attribute, column, value) else klass.connection.case_sensitive_comparison(table, attribute, column, value) end + klass.unscoped.where(comparison) end def scope_relation(record, table, relation) @@ -77,9 +82,9 @@ module ActiveRecord scope_value = record.send(reflection.foreign_key) scope_item = reflection.foreign_key else - scope_value = record.read_attribute(scope_item) + scope_value = record._read_attribute(scope_item) end - relation = relation.and(table[scope_item].eq(scope_value)) + relation = relation.where(scope_item => scope_value) end relation @@ -150,7 +155,7 @@ module ActiveRecord # or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method, # proc or string should return or evaluate to a +true+ or +false+ value. # * <tt>:unless</tt> - Specifies a method, proc or string to call to - # determine if the validation should ot occur (e.g. <tt>unless: :skip_validation</tt>, + # determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>, # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The # method, proc or string should return or evaluate to a +true+ or +false+ # value. |