Проверка пользователя Rails с одним из двух атрибутов, если присутствует, должна быть уникальной

#ruby-on-rails #validation

#ruby-on-rails #проверка

Вопрос:

При определении пользователя с помощью devise в качестве механизма аутентификации, где один из двух атрибутов может служить ключом аутентификации devise :database_authenticatable, :authentication_keys => [:login_name] , основным требованием является

 def at_least_one_identifier
  if [self.email, self.mobile].reject(amp;:blank?).size == 0
    errors[:base] << (I18n.t('user.define_email_or_mobile'))
  end
end
  

что, в свою очередь, потребует проверки ключа аутентификации

 validates :login_name, uniqueness: true
  

Login_name является одним из двух случаев (обратите внимание, что форме присвоено значение по умолчанию nation_id )

 def login_name
  if self.email.nil?
    login_name = self.nation_id amp;amp; self.mobile
  else
    login_name = self.email
  end
end
  

Однако требуются частичные проверки, то есть уникальность электронной почты и мобильного телефона, когда они присутствуют. Таким образом,

   validates :mobile, uniqueness: { scope: :nation_id, message: (I18n.t('user.define_one_mobile_per nation')) }  
  validates :email, uniqueness: true
  

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

Как это можно правильно проверить?

Ответ №1:

Вы должны иметь возможность использовать условную проверку.

 validates :mobile, uniqueness: { scope: :nation_id, message: (I18n.t('user.define_one_mobile_per nation')) }, if: -> { mobile.present? }
validates :email, uniqueness: true, if: -> { email.present? } 
  

Это приведет к тому, что ограничение unique будет проверяться только в том случае, если указанный параметр не nil является уникальным .