173 votes

Déterminer quels attributs ont été modifiés en rappel after_save Rails ?

Je suis la mise en place d'un after_save de rappel dans mon modèle d'observateur pour envoyer une notification uniquement si le modèle est publié attribut a été modifié à partir de la valeur false à true. Puisque les méthodes telles que la changé? ne sont utiles qu'avant, le modèle est enregistré, la façon dont je suis actuellement (et sans succès) en essayant de le faire est comme suit:

def before_save(blog)
  @og_published = blog.published?
end

def after_save(blog)
  if @og_published == false and blog.published? == true
    Notification.send(...)
  end
end

Quelqu'un aurait-il des suggestions quant à la meilleure façon de gérer cela, en utilisant de préférence un modèle observateur rappels (afin de ne pas polluer mon contrôleur de code)?

219voto

Radek Paviensky Points 4193

Dans votre filtre sur le modèle, vous **pouvez** utiliser accesseur (au moins en Rails 3, pas sûr pour 2 Rails). Ainsi, par exemple :

Ça marche.

197voto

Jacek Głodek Points 146

Pour ceux qui veulent connaître les modifications après la sauvegarde, vous devez utiliser

 model.previous_changes
 

cela fonctionne comme model.change mais cela fonctionne toujours après model.save , etc. J'ai trouvé cette information utile alors peut-être que vous aussi.

47voto

zeacuss Points 982

tu peux utiliser ça

 self.changed
 

il retourne un tableau de toutes les colonnes modifiées de cet enregistrement.

vous pouvez aussi utiliser

 self.changes
 

qui retourne un hachage de colonnes qui ont changé et avant et après les résultats sous forme de tableaux

8voto

Jeff Gran Points 458

La réponse "sélectionnée" n'a pas fonctionné pour moi. J'utilise rails 3.1 avec CouchRest :: Model (basé sur Active Model). Les méthodes _changed? ne renvoient pas la valeur true pour les attributs modifiés dans le hook after_update , mais seulement dans le hook before_update . J'ai pu le faire fonctionner avec le (nouveau?) around_update hook:

 class SomeModel < ActiveRecord::Base
  around_update :send_notification_after_change

  def send_notification_after_change
    should_send_it = self.published_changed? && self.published == true

    yield

    Notification.send(...) if should_send_it
  end

end
 

0voto

Maragues Points 9461

J'utilise ceci pour extraire un hachage avec les nouvelles valeurs d'attribut, ce qui m'est utile pour mettre à jour d'autres modèles

 attributes_changed = self.changes.inject(Hash.new){|hash,attr| ((hash[attr[0].to_sym] = attr[1].last) || attr[1].last == false) && hash}
 

le

 attr[1].last == false
 

est nécessaire lorsque la nouvelle valeur est false , où l'affectation renvoie false et "hash" non renvoyé.

Je suppose qu'il y a un moyen plus facile, je suis nouveau sur les rails

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