90 votes

À l’aide de ActiveRecord, y at-il un moyen d’obtenir les vieilles valeurs d’un enregistrement au cours de l’after_update

Le programme d'installation à l'aide d'un exemple simple: j'ai 1 table (Totaux) qui détient la somme de la quantité de la colonne de chaque enregistrement dans une deuxième table (des Choses).

Quand une chose.montant est mis à jour, j'aimerais simplement ajouter la différence entre l'ancienne valeur et la nouvelle valeur de total.la somme.

Maintenant je suis en soustrayant de soi.montant lors de la "before_update" et en ajoutant de l'auto.montant lors de la "après une mise à jour". Cette place de FAÇON de beaucoup de confiance dans la mise à jour de la réussite.

Contrainte: je ne veux pas simplement recalculer la somme de toutes les transactions.

Question: Tout simplement, j'aimerais accéder à la valeur d'origine au cours d'une after_update de rappel. Comment avez-vous trouvé cela?

Mise à jour: je vais avec Luc Francl de l'idée. Au cours d'une "after_update" callback, vous avez toujours accès à l'auto.attr_was les valeurs de ce qui est exactement ce que je voulais. J'ai aussi décidé d'aller avec un "after_update" mise en œuvre parce que je veux garder ce genre de logique dans le modèle. De cette façon, n'importe comment, je décide de transactions de mise à jour à l'avenir, je saurai que je suis à jour de la somme des transactions correctement. Merci à tous pour vos suggestions d'implémentation.

156voto

Luke Francl Points 11707

Idem que tout le monde dit à propos de transactions.

Cela dit...

ActiveRecord comme des Rails 2.1 conserve la trace des valeurs d'attribut d'un objet. Donc, si vous avez un attribut total,, vous aurez une total_changed? méthode et un total_was méthode qui retourne l'ancienne valeur.

Il n'y a pas besoin d'ajouter quelque chose à votre modèle de garder une trace de ce plus.

Mise à jour: Voici la documentation pour ActiveRecord::Sale comme demandé.

11voto

thomax Points 1895

Pour obtenir tous passés respectivement champs, avec leurs valeurs anciennes et nouvelles :

9voto

Gabe Hollombe Points 4687

Les autres personnes sont en mentionnant l'emballage tout cela dans une transaction, mais je pense que c'est fait pour vous; vous avez juste besoin de déclencher la restauration par le déclenchement d'une exception pour les erreurs dans le after_* rappels.

Voir http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

L'ensemble de rappel de la chaîne de sauver, sauver!, ou de détruire les appels à l'intérieur d'une transaction. Qui comprend after_* crochets. Si tout va bien un COMMIT est exécutée une fois que la chaîne a été achevé.

Si un before_* rappel annule l'action d'un ROLLBACK est émise. Vous pouvez également déclencher une RESTAURATION lever une exception dans l'une des rappels, y compris after_* crochets. Notez, cependant, que dans ce cas, le client doit être conscient de cela, parce qu'un ordinaire économiser de soulever une telle exception au lieu de tranquillement retourner false.

6voto

John Topley Points 58789

ActiveRecord::Dirty est un module intégré à ActiveRecord pour le suivi des modifications d’attributs. Vous pouvez utiliser `` pour récupère l’ancienne valeur.

3voto

Daniel Von Fange Points 2739

Ajoutez ceci à votre modèle :

Utilisez ensuite @old_amount dans votre code après mise à jour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X