diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2017-10-04 21:24:08 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-02-21 15:59:26 +0900 |
commit | 6cb176cddfc1541da20da4e75b472c3405f6c933 (patch) | |
tree | 28aea6332d08b12cf9a70509bf845ae7fb0a14bc /activerecord/lib/active_record | |
parent | a7cce501af8e5cb36bcc0a93da10e952d81884dc (diff) | |
download | rails-6cb176cddfc1541da20da4e75b472c3405f6c933.tar.gz rails-6cb176cddfc1541da20da4e75b472c3405f6c933.tar.bz2 rails-6cb176cddfc1541da20da4e75b472c3405f6c933.zip |
Extract `default_uniqueness_comparison` to ease to handle mismatched collation issues
In MySQL, the default collation is case insensitive. Since the
uniqueness validator enforces case sensitive comparison by default, it
frequently causes mismatched collation issues (performance, weird
behavior, etc) to MySQL users.
https://grosser.it/2009/12/11/validates_uniqness_of-mysql-slow/
https://github.com/rails/rails/issues/1399
https://github.com/rails/rails/pull/13465
https://github.com/gitlabhq/gitlabhq/commit/c1dddf8c7d947691729f6d64a8ea768b5c915855
https://github.com/huginn/huginn/pull/1330#discussion_r55152573
This extracts `default_uniqueness_comparison` to ease to handle the
mismatched collation issues on the connection.
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract_adapter.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/validations/uniqueness.rb | 4 |
2 files changed, 7 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 3c9510e469..c1d846f58d 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -506,6 +506,10 @@ module ActiveRecord @connection end + def default_uniqueness_comparison(attribute, value) # :nodoc: + case_sensitive_comparison(attribute, value) + end + def case_sensitive_comparison(attribute, value) # :nodoc: attribute.eq(value) end diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index fb745af125..88ae62c681 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -12,7 +12,7 @@ module ActiveRecord raise ArgumentError, "#{options[:scope]} is not supported format for :scope option. " \ "Pass a symbol or an array of symbols instead: `scope: :user_id`" end - super({ case_sensitive: true }.merge!(options)) + super @klass = options[:class] end @@ -62,6 +62,8 @@ module ActiveRecord if bind.nil? attr.eq(bind) + elsif !options.key?(:case_sensitive) + klass.connection.default_uniqueness_comparison(attr, bind) elsif options[:case_sensitive] klass.connection.case_sensitive_comparison(attr, bind) else |