2009-12-21 16 views
32

Necesito crear una fila en la tabla de tickets y usuarios ... Solo necesito saber cómo procesarla en caso de que la transacción falle.¿Error al manejar las transacciones de ActiveRecord?

@ticket.transaction do 
    @ticket.save! 
    @user.save! 
end 
    #if (transaction succeeded) 
     #..... 
    #else (transaction failed) 
     #...... 
    #end 

En una nota Sólo me gustaría dar las gracias a todos los que participan en el desbordamiento de pila para ayudar a un diseñador de aprender más programación ... Agradezco el tiempo que ustedes sacar de su día para responder preguntas como n00b :) este

Respuesta

50

¡Si está usando el guardado! método con un bang (signo de exclamación), la aplicación emitirá una excepción cuando el guardado falle. Tendría que atrapar la excepción para manejar el error.

begin 
    @ticket.transaction do 
    @ticket.save! 
    @user.save! 
    end 
    #handle success here 
rescue ActiveRecord::RecordInvalid => invalid 
    #handle failure here 
end 
+0

Muchas gracias Matt, lo agradezco :) – Kevin

+7

Una transacción como la del primer fragmento (sin tirar excepciones), no es una transacción de Rails en absoluto. Una transacción como la del segundo fragmento debe rescatar todas las excepciones (rescue => e), gestionar el error y posiblemente volver a plantear la misma excepción. – Ando

+7

Lo siento, Ando, ​​pero claramente es una transacción de ActiveRecord, como lo demuestra el método "transacción". El punto sobresaliente de una transacción es que la primera acción (ticket de guardado) se revierte si la segunda falla. Este fue un ejemplo muy básico para un nuevo desarrollador ... obviamente uno reemplazaría el comentario con el manejo de fallas. Gracias por compartir su perspectiva sobre el manejo de errores, pero el ejemplo proviene de "Desarrollo web ágil con rieles", tal como lo escribió el autor inicial de Rails. Así que me gustaría hacer una excepción en su caracterización de algo que no arroja una excepción como no Rails – MattMcKnight

0

también soy un principiante, pero creo que se puede comprobar @ @ ticket.errors y user.errors y validar de acuerdo a sus respuestas

también ahorrar método debe devolver un valor lógico que determina si el guardado fue exitoso

1

para mí usando Rails 2.3.8 la siguiente fue la mejor solución:

#Important this have to be nil 
result = nil 

@ticket.transaction do 
    result[true, 'Well done'] 

    result = [false, "Ticket can't be saved"] unless @ticket.save! 
    raise ActiveRecord::Rollback unless result[0] 

    result = [false, "User can't be saved"] unless @user.save! 
    raise ActionRecord::Rollback unless result[0] 
end 

if result[0] 
    flash[:notice] = result[1] 
    #... 
else 
    flash[:warning] = result[1] + "<br> Not so well done" 
end 

Asegúrese de que u inicializar resultado como nulo, de modo que usted puede tomar los cambios realizados en el interior de la transacción después de una ¡Retroceder!

Cuestiones relacionadas