diff options
Diffstat (limited to 'config/initializers/active_record_avoid_type_casting_in_uniqueness_validator.rb')
-rw-r--r-- | config/initializers/active_record_avoid_type_casting_in_uniqueness_validator.rb | 104 |
1 files changed, 51 insertions, 53 deletions
diff --git a/config/initializers/active_record_avoid_type_casting_in_uniqueness_validator.rb b/config/initializers/active_record_avoid_type_casting_in_uniqueness_validator.rb index ef4abb77bd7..3e765469995 100644 --- a/config/initializers/active_record_avoid_type_casting_in_uniqueness_validator.rb +++ b/config/initializers/active_record_avoid_type_casting_in_uniqueness_validator.rb @@ -20,75 +20,73 @@ # # This bug was fixed in Rails 5.1 by https://github.com/rails/rails/pull/24745/commits/aa062318c451512035c10898a1af95943b1a3803 -if Gitlab.rails5? - if Rails.version.start_with?("5.1") - raise "Remove this monkey patch: #{__FILE__}" - end +if Rails.version.start_with?("5.1") + raise "Remove this monkey patch: #{__FILE__}" +end - # Copy-paste from https://github.com/kamipo/rails/blob/aa062318c451512035c10898a1af95943b1a3803/activerecord/lib/active_record/validations/uniqueness.rb - # including local fixes to make Rubocop happy again. - module ActiveRecord - module Validations - class UniquenessValidator < ActiveModel::EachValidator # :nodoc: - def validate_each(record, attribute, value) - finder_class = find_finder_class_for(record) - table = finder_class.arel_table - value = map_enum_attribute(finder_class, attribute, value) +# Copy-paste from https://github.com/kamipo/rails/blob/aa062318c451512035c10898a1af95943b1a3803/activerecord/lib/active_record/validations/uniqueness.rb +# including local fixes to make Rubocop happy again. +module ActiveRecord + module Validations + class UniquenessValidator < ActiveModel::EachValidator # :nodoc: + def validate_each(record, attribute, value) + finder_class = find_finder_class_for(record) + table = finder_class.arel_table + value = map_enum_attribute(finder_class, attribute, value) - relation = build_relation(finder_class, table, attribute, value) + relation = build_relation(finder_class, table, attribute, value) - if record.persisted? - if finder_class.primary_key - relation = relation.where.not(finder_class.primary_key => record.id_was || record.id) - else - raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.") - end + if record.persisted? + if finder_class.primary_key + relation = relation.where.not(finder_class.primary_key => record.id_was || record.id) + else + raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.") end + end - relation = scope_relation(record, table, relation) - relation = relation.merge(options[:conditions]) if options[:conditions] + relation = scope_relation(record, table, relation) + relation = relation.merge(options[:conditions]) if options[:conditions] - if relation.exists? - error_options = options.except(:case_sensitive, :scope, :conditions) - error_options[:value] = value + if relation.exists? + error_options = options.except(:case_sensitive, :scope, :conditions) + error_options[:value] = value - record.errors.add(attribute, :taken, error_options) - end - rescue RangeError + record.errors.add(attribute, :taken, error_options) end + rescue RangeError + end - protected - - def build_relation(klass, table, attribute, value) #:nodoc: - if reflection = klass._reflect_on_association(attribute) - attribute = reflection.foreign_key - value = value.attributes[reflection.klass.primary_key] unless value.nil? - end + protected - # the attribute may be an aliased attribute - if klass.attribute_alias?(attribute) - attribute = klass.attribute_alias(attribute) - end + def build_relation(klass, table, attribute, value) #:nodoc: + if reflection = klass._reflect_on_association(attribute) + attribute = reflection.foreign_key + value = value.attributes[reflection.klass.primary_key] unless value.nil? + end - attribute_name = attribute.to_s + # the attribute may be an aliased attribute + if klass.attribute_alias?(attribute) + attribute = klass.attribute_alias(attribute) + end - column = klass.columns_hash[attribute_name] - cast_type = klass.type_for_attribute(attribute_name) + attribute_name = attribute.to_s - comparison = - if !options[:case_sensitive] && !value.nil? - # 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 + column = klass.columns_hash[attribute_name] + cast_type = klass.type_for_attribute(attribute_name) - if value.nil? - klass.unscoped.where(comparison) + comparison = + if !options[:case_sensitive] && !value.nil? + # will use SQL LOWER function before comparison, unless it detects a case insensitive collation + klass.connection.case_insensitive_comparison(table, attribute, column, value) else - bind = Relation::QueryAttribute.new(attribute_name, value, cast_type) - klass.unscoped.where(comparison, bind) + klass.connection.case_sensitive_comparison(table, attribute, column, value) end + + if value.nil? + klass.unscoped.where(comparison) + else + bind = Relation::QueryAttribute.new(attribute_name, value, cast_type) + klass.unscoped.where(comparison, bind) end end end |