2012-03-06 6 views
7

En mi aplicación, a veces creo un usuario sobre la marcha, y el correo electrónico de un usuario debe ser un formato válido y ser únicorails 3.1: cómo puede la aplicación manejar diferentes "razones" para ActiveRecord :: RecordInvalid (por ejemplo, duplicado vs error de validación)

Me gustaría redirigir a diferentes lugares según la validación que provocó el error: formato no válido frente a duplicado.

En mi código que tengo

begin 
     user.save! 
     flash[:notice] = "Created new user #{email} with password #{password}" 

    rescue ActiveRecord::RecordInvalid => e 
     flash[:alert] = "Failed to create account because #{e.message}" 
     redirect_to SOMEPLACE 
    end 

Si el correo electrónico es un formato no válido (como "usuario @ ejemplo") e.Message es "Error de validación: El correo electrónico es inválida"

Si el correo electrónico ya existe en la tabla, e.message es "Validación fallida: el correo electrónico ya se ha tomado"

Odio la idea de analizar el texto de e.message para determinar el motivo ... ¿hay alguna manera mejor para un manejador de rescate? para detectar el motivo subyacente una excepción ActiveRecord :: RecordInvalid w como arrojado?

P.S. Sé en este ejemplo que puedo simplemente verificar el correo electrónico existente antes de hacer un guardado, pero estoy tratando de comprender la solución general para detectar y actuar sobre diferentes fallas de validación arrojando la misma excepción.

+1

En realidad, no podemos simplemente verificar el correo electrónico ya existente, las validaciones de singularidad de ActiveRecord están sujetas a condiciones de carrera y no están definidas. Debe tener una restricción de exclusividad dentro de su base de datos y debe estar preparado para o tratar con la excepción que aumentará (ya sea de '.save' o' .save! '). –

Respuesta

1

La forma estándar de rieles de hacerlo es no utilizar el operador de explosión, lo que plantea una excepción, sino utilizar el estándar método para guardar y verificar si devuelve verdadero o falso:

if @user.save 
    flash[:notice] = "User created." 
    redirect_to :action => :index 
else 
    flash[:alert] = "User could not be created." 
    render :action => :new 
end 

Y en su vista del usuario la creación:

<% if @user.errors.any? %> 
    <ul> 
    <% @user.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
    <% end %> 
    </ul> 
<% end %> 
+0

Pero eso no te dice por qué falló la operación de guardar. Si tienes una restricción única dentro de tu base de datos (que deberías como validación de exclusividad de AR está sujeta a las condiciones de carrera) entonces puedes hacer que 'x.valid?' Sea verdadero, pero tanto 'x.save' como' x.save! 'Pueden generar una excepción porque se violó la restricción de la base de datos. –

0

Si estoy entendiendo lo que está tratando de hacer correctamente, una manera de hacer esto sería justo afirmar contra la presencia de un error en el nivel de campo. p.ej.

if user.errors[:field_name].present? 
    redirect_to path_for_field_name_error 
end 

Alternativamente, se definen algunos mapeo de los campos que redirigen donde como una constante (por ejemplo REDIRECT_PATHS en cuyo caso se termina con algo como:

redirect_to REDIRECT_PATHS[field_name] if user.errors[:field_name].present? 

donde se puede simplemente bucle sobre los field_name s

+0

En mi ejemplo, pueden ocurrir varios errores para el mismo campo, por ejemplo, la dirección de correo electrónico podría no ser válida o ser utilizada. – jpwynn

+0

K. Si de alguna manera puede utilizar los integradores de ActiveRecord para manejar todo lo que no es esta restricción de exclusividad controlada por la base de datos (que @mu es demasiado corta, señala correctamente que no siempre funciona como se esperaba), entonces usted podría simplemente verificar contra '.valid?' y quita los errores de esa manera, excepto esta restricción de exclusividad. Por supuesto, si tiene múltiples restricciones en otros campos, sigue siendo un problema y recurre al análisis de cadenas. Buena suerte, ¿eso es útil? –

Cuestiones relacionadas