2011-02-20 6 views
47

Selon save bang your head, active record will drive you mad, nous devrions éviter d'utiliser save! et rescue idiome pour des situations exceptionnelles. Compte tenu de cela, disons qu'un modèle doit @post.mark_rejected.Quand utiliser `save` vs` save! `Dans le modèle?

Si le code mark_rejected échoue en raison de l'un des problèmes ci-dessous, une exception doit-elle être levée? :

  • s'il y a un problème de validation
  • si un champ non annulable était attribué une valeur nulle
  • s'il y avait une perte de connexion à la base de données

Si nous ne jeter une exception, alors:

  • action du contrôleur devrait vérifier la valeur de retour de mark_rejected et de le faire est chose
  • nous n'attendons pas d'exception de cet appel de méthode, donc nous n'écrivons pas une clause rescue dans l'action du contrôleur, donc l'exception monte en bulles jusqu'à (..wherever ..) et apparaîtra probablement comme une (500 HTTP ?) erreur

code Exemple:

def mark_rejected 
    ... 
    save! 
end 

ou

def mark_rejected 
    ... 
    save 
end 
+4

@Zabba Voici le [code source et documentation de 'save' et' save! '] (Https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb# L86). – JJD

Répondre

18

Il y a plus de frais généraux à une exception, donc il y a un problème de performance, especi allié quand on peut s'attendre à ce qu'il sera probablement lancé souvent, comme c'est le cas avec save. Il y a moins de lignes de code pour vérifier si la valeur de retour est fausse que sauver une exception, donc je ne vois pas comment c'est un problème de vérifier la valeur de retour si vous avez déjà besoin de sauver l'exception. À quelle fréquence une exception lancée par save! doit-elle jamais augmenter la pile d'appels dans la pratique? Rarement, si jamais, dans mon expérience. Si une exception est levée lors de l'appel de save par opposition à save!, vous devez afficher une page d'erreur 500 car c'est ce qui s'est produit: une erreur de serveur interne irrécupérable, inconnue et inattendue.

+1

Merci pour votre aide aujourd'hui. J'ai lu un peu au sujet des exceptions maintenant, et suis venu à la conclusion que les exceptions ne devraient pas être utilisées pour "contrôle de flux" pour ainsi dire. S'il y a une exception, je vais le laisser gonfler la pile d'appels et écrire à la place du code de vérification de valeur pour résoudre les problèmes. À l'heure actuelle l'approche semble la bonne manière de faire ces choses, bien que je ne sois pas entièrement sûr des raisons. Tant pis. – Zabba

99

save! déclenchera une erreur si elle échoue.

save retournera une valeur booléenne comme vrai ou faux.

+0

Quelle est la commande opposée pour enregistrer! Je veux dire quelle est la commande pour supprimer l'utilisateur? – user1903022

+0

'user.delete' et' user.supprimer »Il va supprimer l'utilisateur – Selvamani

+0

@Selvamani: user.remove? – ram