2009-12-21 5 views
32

J'ai besoin de créer une ligne dans les deux tickets et la table des utilisateurs ... J'ai juste besoin de savoir comment traiter en cas d'échec de la transaction.Traitement des erreurs dans les transactions ActiveRecord?

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

Sur une note de côté, je voudrais simplement remercier tous ceux qui participe à un débordement de pile pour aider un designer en savoir plus ... programmation Je vous remercie du temps que vous les gars prennent de votre journée pour répondre à des questions comme n00b :) ce

Répondre

50

Si vous utilisez la sauvegarde! méthode avec un bang (point d'exclamation), l'application lancera une exception lorsque l'enregistrement échoue. Vous devrez alors attraper l'exception pour gérer l'échec.

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

Merci beaucoup Matt, je l'apprécie :) – Kevin

+7

Une transaction comme celle du premier extrait (sans exception de lancement), n'est pas du tout une transaction Rails. Une transaction comme celle du second extrait devrait sauver toutes les exceptions (rescue => e), gérer l'échec et éventuellement lever à nouveau la même exception. – Ando

+7

Désolé Ando, ​​mais il s'agit clairement d'une transaction ActiveRecord, comme en témoigne la méthode "transaction". Le point saillant d'une transaction est que la première action (ticket de sauvegarde) est annulée si la seconde échoue. C'était un exemple très basique pour un nouveau développeur ... évidemment on remplacerait le commentaire par la gestion des échecs. Merci d'avoir partagé votre point de vue sur la gestion des erreurs, mais l'exemple vient de "Agile Web Development avec Rails", comme écrit par l'auteur initial de Rails! Donc, je prendrais une exception à votre caractérisation de quelque chose qui ne jette pas une exception comme non Rails – MattMcKnight

0

je suis aussi un débutant, mais je crois que vous pouvez vérifier @ ticket.errors et @ user.errors et valider en fonction de leurs réponses

aussi la méthode de sauvegarde doit renvoyer un booléen qui détermine si la sauvegarde a réussi

1

pour moi en utilisant Rails 2.3.8 ci-après est la meilleure solution:

#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 

Assurez-vous que u initialize résultat que nul, afin que vous puissiez prendre les modifications apportées à l'intérieur de la transaction après une Rollback!

Questions connexes