Validación inesperada en el modelo de Usuario con autenticación de Devise.
Una aplicación que utiliza Devise ha configurado el inicio de sesión con un atributo específico:
config.authentication_keys = [:login_name]
Este atributo se define mediante un método de usuario donde un inicio de sesión requiere ya sea un correo electrónico o un número de teléfono móvil.
Este último es distinto de ‘0’ para permitir un atributo poblado que luego se puede comparar para verificar su unicidad.
devise :database<em>authenticatable, :authentication</em>keys => [:login_name]
validate :atleastoneidentifier
validates :mobile, uniqueness: { scope: :nationid, message: (I18n.t(‘user.defineonemobilepernation’)) }, if: -> { mobile != 0 }
validates :email, uniqueness: true, if: -> { email.present? }
def atleastoneidentifier
if [self.email, self.mobile].reject(&:blank?).size == 0
errors[:base] << (I18n.t(‘user.defineemailormobile’))
end
end
Al ejecutar una prueba, depurando el proceso
loginname = ‘+19991112200’
user = User.new(mobile: 9991112200, loginname: loginname, password: ‘11111111’, passwordconfirmation: ‘11111111’ )
user.valid?
puts user.errors.first.to_s
“`
se identifica el siguiente error:
activerecord.errors.models.user.attributes.email.blank
Esta no es una validación que debería activarse.
Mientras que este enlace sugiere sobrescribir un método, el nombre del método find_for_database_authentication
no es indicativo de una validación específica y se refiere más a la acción de inicio de sesión que al proceso de registro: “cambia el comportamiento de la acción de inicio de sesión”.
No hay validaciones relacionadas con el correo electrónico dentro del modelo de usuario. Se sospecha que Devise está estableciendo este requisito, ¿pero dónde?
davy.ai
Solución:
Devise tiene un módulo llamado
Validatable
que define un conjunto de validaciones predeterminadas para el modelo de usuario. Una de estas validaciones predeterminadas requiere la presencia de un atributo de correo electrónico. Dado que:email
es una de las opciones habilitadas de forma predeterminada en el módulodatabase_authenticatable
de devise, se espera que esté presente para una cuenta de usuario válida.Para desactivar la validación de correo electrónico, debemos anular el módulo
validateable
y sus métodos asociados en nuestro modelo de usuario de la siguiente manera:Estos métodos
email_required?
yemail_changed?
están definidos en el móduloValidatable
para hacer cumplir la presencia del atributo de correo electrónico. Al anularlos en nuestro modelo de usuario, podemos desactivar el requisito del atributo de correo electrónico y mantener intactos otros módulos de devise comodatabase_authenticatable
.Con estos cambios, cuando el código de prueba se ejecute y valide el objeto de usuario, la validación del atributo de correo electrónico ya no se activará y el mensaje de error debería desaparecer.