38

Używam restful_authentication w mojej aplikacji. Tworzę zestaw domyślnych użytkowników za pomocą zadania rake, ale za każdym razem, gdy uruchamiam zadanie, wysyłana jest wiadomość aktywacyjna z powodu obserwatora powiązanego z moim modelem użytkownika. Ustawiam pola aktywacyjne, kiedy tworzę użytkowników, więc aktywacja nie jest konieczna.Prosty sposób wyłączania obserwatorów podczas rake task?

Ktoś wie o łatwym sposobie ominięcia obserwatorów podczas uruchamiania zadania rake, aby żadne e-maile nie zostały wysłane podczas zapisywania użytkownika?

Dzięki.

Odpowiedz

7

Można dodać akcesor do modelu użytkownika, coś jak „skip_activation”, które nie muszą być zapisane, ale utrzymują się przez sesję, a następnie sprawdzić flagę w obserwatora. Coś jak

class User 
    attr_accessor :skip_activation 
    #whatever 
end 

Następnie w obserwatora:

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

Nie ma prosty sposób wyłączyć obserwatorów o tym nie wiem, ale brzmi to możliwe aby dodać logikę do obserwatora nie wysłać e-mail, gdy jest ustawiony kod aktywacyjny ...

2

Na ogół, dla tego rodzaju sytuacjach, można:

  1. Skonfiguruj atrapa obiektu do „wchłonięcia” niechcianych zachowań
  2. masz zewnętrznie dostępne flagi/wyłącznik, że obserwatorzy respektować hamować zachowanie
  3. Dodaj logikę obserwatorowi, by dete ct, gdy zachowanie jest niepotrzebne ogólnie (np. co dbarker wskazuje)
  4. mieć globalną flagę „testowanie”, „debug”, „Uruchomienie” lub cokolwiek, że zmiany w zachowaniu niski poziom
  5. introspekcji i usuwania obserwatorów
  6. Dodaj metodę do modelu, który wykonuje alternatywę , nieobserwowana wersja zadania (dzielenie implementacji z normalną metodą tak dużo jak to możliwe).

W tym przypadku, powiedziałbym, że nr 3 to Twój najlepszy zakład.

0

Jak inni napomknęli; Zawinęłbym niechcianą logikę w twoim Obserwatorze za pomocą prostej instrukcji if.

def after_create 
    send_email if RAILS_ENV == "production" 
end 
2

Gdy uruchomione testy na aplikację pracuję nad używam następujące:

Model.delete_observers 
1

Można przyjąć metodę poza obserwatorem;

MessageObserver.send(:remove_method, :after_create) 

Zatrzyma: after_create na MessageObserver, usuwając go.

2

Wyłączenie obserwatorów do szyny 3 jest prosta:

Rails.configuration.active_record.observers = [] 
6

Kolejnym można spróbować (szyny 3)

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

To całkowicie rozwiązało problem dla mnie. Dzięki! – Sixty4Bit

+0

to też działa dla mnie !, ale chciałbym dodać dodatkowe warunkowanie ARGV [0] == "db: migrate", ponieważ możesz w przyszłości napisać zadanie rake, które wykorzystuje twoich obserwatorów i możesz zapomnieć o tej małej linii i wyciągnij włosy, próbując dowiedzieć się, dlaczego twoi obserwatorzy nie biegają podczas twojego nowego, skomplikowanego zadania rake ... –

1

Przyszedłem tutaj szukając odpowiedzi do tego samego ... Nie Powyższe zdawało się robić sztuczkę (lub wymagać dodania logiki specyficznej dla migracji do mojego kodu aplikacji - boo).

Oto co wymyśliłem (trochę lame, że musi iść w każdej odpowiedniej migracji, ale ...)

class ChangeSomething < ActiveRecord::Migration 

    # redefine... 
    class MessageObserver < ActiveRecord::Observer 
    def after_create(observed) ; end 
    def after_update(observed) ; end 
    end 

    def self.up 
    # Message create/update stuff... 
    end 
end 
8

jako flaga dla obserwatora lubię zdefiniować akcesor klasy o nazwie „wyłączone”, tak to brzmi tak:

class ActivityObserver < ActiveRecord::Observer 
    observe :user 

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

kładę ją jako warunek wrażliwych callbacków

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

a ja po prostu włączyć flagę na kiedy potrzebne

ActivityObserver.disabled=true 
119

Rails 3.1 w końcu pochodzi z API dla tego: http://api.rubyonrails.org/v3.1.0/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 

Gdzie ORM mogłaby być na przykład ActiveRecord::Base

+0

To zdecydowanie najlepsza odpowiedź tutaj :-) –

+0

Żadne z tych nie przysiada mi. Skończyło się na tym, że zamieniłem je na zadania rake w application.rb. – mhenrixon

+1

Co większość ludzi używa zamiast "ORM"? –

1
User.skip_callback("create", :after, :send_confirmation_email) 

.... 

User.set_callback("create", :after, :send_confirmation_email) 

Więcej na tej podstawie:

Disabling Callbacks in Rails 3

Powiązane problemy