aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2018-09-18 07:23:38 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-01-11 17:32:48 +0900
commiteb5fef554fde84d36b45191182ed98bd344dc967 (patch)
tree9f8b83bee569bcd8a75c093748d73e46cf488417 /activerecord/lib/active_record/validations
parent235eb91bad58ab18b45aa36fa3a1ebedfe1c4879 (diff)
downloadrails-eb5fef554fde84d36b45191182ed98bd344dc967.tar.gz
rails-eb5fef554fde84d36b45191182ed98bd344dc967.tar.bz2
rails-eb5fef554fde84d36b45191182ed98bd344dc967.zip
Refactor `build_relation` in the uniqueness validator to avoid low level predicate construction
Diffstat (limited to 'activerecord/lib/active_record/validations')
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb33
1 files changed, 13 insertions, 20 deletions
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 5a1dbc8e53..19ba2b8cd9 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -61,28 +61,21 @@ module ActiveRecord
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)
+ relation = klass.unscoped
+ comparison = relation.bind_attribute(attribute, value) do |attr, bind|
+ return relation.none! unless bind.boundable?
+
+ if bind.nil?
+ attr.eq(bind)
+ elsif options[:case_sensitive]
+ klass.connection.case_sensitive_comparison(attr, bind)
+ else
+ # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
+ klass.connection.case_insensitive_comparison(attr, bind)
+ end
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)
+ relation.where!(comparison)
end
def scope_relation(record, relation)