aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations/uniqueness.rb
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2017-08-01 17:34:14 -0400
committerRafael Mendonça França <rafaelmfranca@gmail.com>2017-08-01 17:34:14 -0400
commitfeb1ddae021c38174f9c22bbd1298c8b73431b45 (patch)
tree09a38695596cf80dc362dd4d93cf94d6f7415e7b /activerecord/lib/active_record/validations/uniqueness.rb
parent3540e60c385286f3517ff56270b31a91ed3024a3 (diff)
parentf9a43f28c087f8ffd35ff7c33a60c938b60f2be2 (diff)
downloadrails-feb1ddae021c38174f9c22bbd1298c8b73431b45.tar.gz
rails-feb1ddae021c38174f9c22bbd1298c8b73431b45.tar.bz2
rails-feb1ddae021c38174f9c22bbd1298c8b73431b45.zip
Merge remote-tracking branch 'origin/master' into unlock-minitest
Diffstat (limited to 'activerecord/lib/active_record/validations/uniqueness.rb')
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb30
1 files changed, 29 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 154cf5f1a4..2677fade18 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActiveRecord
module Validations
class UniquenessValidator < ActiveModel::EachValidator # :nodoc:
@@ -50,7 +52,33 @@ module ActiveRecord
end
def build_relation(klass, attribute, value)
- klass.unscoped.where!({ attribute => value }, options)
+ if reflection = klass._reflect_on_association(attribute)
+ attribute = reflection.foreign_key
+ value = value.attributes[reflection.klass.primary_key] unless value.nil?
+ end
+
+ if value.nil?
+ return klass.unscoped.where!(attribute => value)
+ end
+
+ # the attribute may be an aliased attribute
+ if klass.attribute_alias?(attribute)
+ attribute = klass.attribute_alias(attribute)
+ end
+
+ attribute_name = attribute.to_s
+ value = klass.predicate_builder.build_bind_attribute(attribute_name, value)
+
+ table = klass.arel_table
+ column = klass.columns_hash[attribute_name]
+
+ comparison = if !options[:case_sensitive]
+ # 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, relation)