39 votes

Un moyen simple de désactiver les observateurs pendant la tâche de ratissage ?

J'utilise restful_authentication dans mon application. Je crée un ensemble d'utilisateurs par défaut en utilisant une tâche rake, mais à chaque fois que je lance la tâche, un email d'activation est envoyé à cause de l'observateur associé à mon modèle d'utilisateur. Je définis les champs d'activation lorsque je crée les utilisateurs, de sorte qu'aucune activation n'est nécessaire.

Quelqu'un connaît-il un moyen facile de contourner les observateurs tout en exécutant une tâche rake afin qu'aucun courriel ne soit envoyé lorsque je sauvegarde l'utilisateur ?

Merci.

120voto

parapet Points 1251

Rails 3.1 propose enfin une API pour cela : http://api.rubyonrails.org/classes/ActiveModel/ObserverArray.html#method-i-disable

ORM.observers.disable :user_observer
  # => disables the UserObserver

User.observers.disable AuditTrail
  # => disables the AuditTrail observer for User notifications.
  #    Other models will still notify the AuditTrail observer.

ORM.observers.disable :observer_1, :observer_2
  # => disables Observer1 and Observer2 for all models.

ORM.observers.disable :all
  # => disables all observers for all models.

User.observers.disable :all do
  # all user observers are disabled for
  # just the duration of the block
end

8voto

fsainz Points 81

En tant qu'indicateur pour l'observateur, j'aime définir un accesseur de classe appelé "disabled", qui se lit comme suit :

class ActivityObserver < ActiveRecord::Observer
  observe :user

  # used in tests to disable the observer on demand.
  cattr_accessor(:disabled)
end

Je l'ai mis comme une condition dans les callbacks sensibles

def after_create(record)
       return if ActivityObserver.disabled
       # do_something
end

et je n'allume le drapeau que lorsque c'est nécessaire

ActivityObserver.disabled=true

8voto

Terry Points 742

Vous pourriez ajouter un accesseur à votre modèle d'utilisateur, quelque chose comme "skip_activation", qui n'aurait pas besoin d'être enregistré, mais qui persisterait dans la session, puis vérifierait le drapeau dans l'observateur. Quelque chose comme

class User
  attr_accessor :skip_activation
  #whatever
end

Ensuite, dans l'observateur :

def after_save(user)
  return if user.skip_activation
  #rest of stuff to send email
end

6voto

Nathan Bertram Points 190

Un autre que vous pouvez essayer (rails 3)

config.active_record.observers = :my_model_observer unless File.basename($0) == 'rake'

2voto

MarkusQ Points 15612

En général, pour ce genre de situations, vous pouvez :

  1. Créez un objet fantaisie pour "absorber" le comportement indésirable.
  2. Disposer d'un drapeau / interrupteur accessible de l'extérieur que les observateurs respectent pour inhiber le comportement.
  3. Ajouter une logique à l'observateur pour détecter quand le comportement n'est pas nécessaire. en général (par exemple, ce que suggère dbarker)
  4. Avoir un drapeau global "testing", "debug", "startup" ou autre qui change le comportement de bas niveau.
  5. Introspecter et éliminer les observateurs
  6. Ajoutez à votre modèle une méthode qui exécute une version alternative, non observée, de la tâche (en partageant autant que possible la mise en œuvre avec la méthode normale).

Dans ce cas, je dirais que le n°3 est votre meilleure option.

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