Условная проверка чувствительности к регистру в модели - PullRequest
1 голос
/ 05 марта 2020

У меня есть одна проверка модели, как показано ниже

validates :value, presence: true, allow_blank: false, uniqueness: { scope: [:account_id, :provider] }

Я хочу добавить еще одно условие case_sensitive внутри уникальности, как показано ниже

validates :value, presence: true, allow_blank: false, uniqueness: { scope: [:account_id, :provider], case_sensitive: :is_email? }

def is_email?
  provider != email
end

Короче говоря, оно не должно проверять case_sensitive, когда провайдер электронной почты - это не электронная почта, но в настоящее время он не работает, он ожидает истину или ложь только без какого-либо метода или каких-либо условий.

Как мне добиться этого в рельсах? Я уже написал пользовательскую проверку, потому что она не работала.

ОБНОВЛЕНИЕ

, если я добавлю еще одну проверку, как показано ниже

validates_uniqueness_of :value, case_sensitive: false, if: -> { provider == 'email' }

Это дает мне ту же ошибку дважды :value=>["has already been taken", "has already been taken"]

1 Ответ

2 голосов
/ 05 марта 2020

В указанном c случае case_sensitive значение, переданное параметру, всегда будет сравниваться с его истинным значением.

Как видно из класса UniquenessValidator, когда построено отношение, он использует переданные параметры, чтобы проверить, является ли значение case_sensitive истинным (не ложным или нулевым), если это так, он принимает ветвь elsif условие:

def build_relation(klass, attribute, value)
  ...
    if !options.key?(:case_sensitive) || bind.nil?
      klass.connection.default_uniqueness_comparison(attr, bind, klass)
    elsif options[:case_sensitive] # <--------------------------------- sadly, this returns true for :is_email?
      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

Когда вы передаете имя метода is_email? в case_sensitive, который фактически является символом, условие принимает эту ветвь.

tl; dr; , Вы всегда должны использовать true или false с case_sensitive.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...