2009-12-21 17 views
32

Ho bisogno di creare una riga in entrambi i ticket e la tabella degli utenti ... Ho solo bisogno di sapere come elaborare nel caso in cui la transazione fallisce.Gestione errori nelle transazioni ActiveRecord?

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

Su un lato nota Vorrei solo ringraziare tutti coloro che partecipa al overflow dello stack per aiutare un progettista saperne di più di programmazione ... Apprezzo il tempo che voi ragazzi tirano fuori della vostra giornata per rispondere a domande come n00b questo :)

risposta

50

Se stai usando il salvataggio! metodo con un botto (punto esclamativo), l'applicazione genererà un'eccezione quando il salvataggio fallisce. Dovresti quindi rilevare l'eccezione per gestire l'errore.

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

Grazie mille Matt, lo apprezzo :) – Kevin

+7

Una transazione come quella nel primo frammento (senza generare eccezioni), non è affatto una transazione Rails. Una transazione come quella nel secondo snippet dovrebbe salvare tutte le eccezioni (rescue => e), gestire l'errore ed eventualmente aumentare nuovamente la stessa eccezione. – Ando

+7

Scusa Ando, ​​ma è chiaramente una transazione ActiveRecord, come evidenziato dal metodo "transazione". Il punto saliente di una transazione è che la prima azione (ticket di salvataggio) viene annullata se il secondo fallisce. Questo era un esempio molto semplice per un nuovo sviluppatore ... ovviamente si sarebbe sostituito il commento con la gestione degli errori. Grazie per aver condiviso la tua prospettiva sulla gestione degli errori, ma l'esempio deriva da "Agile Web Development with Rails", come scritto dall'autore iniziale di Rails! Quindi, farei un'eccezione alla tua caratterizzazione di qualcosa che non genera un'eccezione in quanto non Rails – MattMcKnight

0

io sono anche un principiante, ma credo che è possibile controllare @ ticket.errors e @ user.errors e convalidare in base alle loro risposte

anche il salvataggio metodo deve restituire un valore booleano che determina se il salvataggio ha avuto esito positivo

1

per me usando Rails 2.3.8 Quanto segue è stato la soluzione migliore:

#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 

Assicurarsi che u inizializzare risultato come pari a zero, in modo da poter prendere le modifiche apportate all'interno della transazione dopo un rollback!