2011-03-12 14 views
9

Cuando implementé por primera vez un modelo de usuario, permití al usuario escribir el correo electrónico en mayúscula o minúscula para su información de inicio de sesión. El problema es que es una aplicación móvil y, a veces, las autocaps suceden para que el usuario no se autentique. He cambiado el método CREATE para descifrar el correo electrónico primero. Sin embargo, esto hace que las personas con cuentas existentes no sean consistentesCampo de downcase masivo para todos los registros en rieles

Entonces, ¿cómo puedo agregar una migración para actualizar masivamente el campo de correo electrónico en la tabla de usuarios para descifrarlo?

+2

direcciones de correo electrónico están entre mayúsculas y minúsculas, por lo que siempre se debe doblar a minúscula para la comparación y el almacenamiento. Es una de esas cosas que se pasan por alto durante el diseño de la aplicación ... una vez ... luego lo recuerdas para siempre. :-) –

Respuesta

5

La solución más simple es usar el código Ruby:

class DowncaseEmail < ActiveRecord::Migration 
    def up 
    User.all.each do |user| 
     user.update_attributes :email => user.email.downcase 
    end 
    end 
end 

Como otros han señalado, esta no es la solución más eficiente. Tiendo a preferir la portabilidad al rendimiento, pero eso depende de la cantidad de registros de los que estamos hablando.

una solución más compleja, pero todavía portátil depende de algunas funciones específicas DB:

class DowncaseEmail < ActiveRecord::Migration 
    def up 
    if %w[MySQL PostgreSQL].include? ActiveRecord::Base.connection.adapter_name 
     execute "UPDATE users SET email = LOWER(email)" 
    else 
     User.all.each do |user| 
     user.update_attributes email: user.email.downcase 
     end 
    end 
    end 
end 

Tanto Postgres y MySQL soporte la función de LOWER. SQLite también lo admite, pero solo para la codificación ascii, que probablemente esté bien para los correos electrónicos, pero podría causar errores (ya que algunos correos electrónicos pueden contener otros caracteres). Rails también admite potencialmente cualquier cantidad de bases de datos, por lo que depender de estas funciones puede hacer que su aplicación quede bloqueada en un DB específico.

21

La forma más eficiente sería evitar el uso de un iterador de Ruby, y hacerlo directamente en SQL.

Dentro de un archivo de migración normal se puede utilizar este SQL para MySQL:

execute("UPDATE users SET email = LOWER(email)") 
+0

Por lo general, habrá que cambiar un código además, por lo que las comparaciones se realizarán en minúsculas, y los registros recién insertados se doblarán en minúsculas para evitar que el problema vuelva a ocurrir. –

2

no tendrá que preocuparse acerca de cómo optimizar algo que sólo va a hacer una vez. A menos que tenga un gran número de usuarios, solo use la metodología que le sea más familiar. (Aunque yo recomendaría acaba de ejecutar la consulta SQL.)

+0

Gracias a todos por las soluciones. Solo tenía unos 300 usuarios, así que hacer una migración simple fue lo más fácil para mí. Aclamaciones. – JBlake

2

usted puede ir simplemente con

User.update_all('email = lower(email)') 
+0

ama esta solución. – nfriend21

Cuestiones relacionadas