diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2018-09-18 07:23:38 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-01-11 17:32:48 +0900 |
commit | eb5fef554fde84d36b45191182ed98bd344dc967 (patch) | |
tree | 9f8b83bee569bcd8a75c093748d73e46cf488417 /activerecord/lib/active_record/validations | |
parent | 235eb91bad58ab18b45aa36fa3a1ebedfe1c4879 (diff) | |
download | rails-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.rb | 33 |
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) |