Imaginons que vous ayez une classe qui publie des articles. L'action de publication provoque l'envoie d'un e-mail au modérateur qui est averti de la nouvelle publication. Un moyen de ne pas avoir à appeler de méthode d'envoi de mail dans votre fonction de publication est d'utiliser par le pattern Observer.
Avec Rails, il est possible de déclarer des classes observatrices de vos modèles de la manière suivante.
Reprenons notre classe Article :
class Article < ActiveRecord::Base def publish @article = Article.find(params[:id]) @article.status = "published" @article.save end end
Vous remarquerez que dans cette classe nous n'avons pas envoyé d'email, et c'est là qu'intervient Observer. On crée une autre classe ArticleNotificationObserver qui étend la classe Observer (qui est un Singleton par ailleurs) qui va observer notre modèle.
class ArticleNotificationObserver < ActiveRecord::Observer observe Article cattr_accessor(:disabled) def after_save(article) unless disabled if status_changed? && status == 'published' # traitement envoi d'emails end end end end
En fait Rails nous permet de capturer des callbacks, il y en a une dizaine after_save, before_save, after_update, before_update, etc... Je vous laisser aller voir les actions possibles dans la doc : .
Vous noterez également deux choses, un attribut de classe (disabled) qui sert pour que lorsque vous effectuez des migrations sur la table Article, que l'observer ne soit pas appelé en ajoutant dans votre migration :
Article.disabled = true
et la possibilité en rails, d'appeler des méthodes "nom_colonne"_changed? et "nom_colonne".changes pour savoir si la valeur de la colonne a changé et quels en sont les changements.
Enfin, pour que cela fonctionne, il faut déclarer dans la configuration de rails (environment.rb) les observers (pensez à redémarrer le serveur):
config.active_record.observers = :article_notification_observer
Si vous avez des corrections ou des précisions à apporter, n'hésitez pas.