38

Sto utilizzando restful_authentication nella mia app. Sto creando una serie di utenti predefiniti utilizzando un'attività rake, ma ogni volta che eseguo l'attività viene inviata un'e-mail di attivazione a causa dell'osservatore associato al mio modello utente. Sto impostando i campi di attivazione quando creo gli utenti, quindi non è necessaria alcuna attivazione.Semplice modo di disattivare gli osservatori durante il rake task?

Qualcuno sa di un modo semplice per bypassare gli osservatori durante l'esecuzione di un'attività rake in modo che nessuna email venga inviata quando salvi l'utente?

Grazie.

risposta

7

Si potrebbe aggiungere una funzione di accesso al vostro modello utente, qualcosa come "skip_activation", che non avrebbe bisogno di essere salvato, ma avrebbe persistere attraverso la sessione, e quindi controllare la bandiera nell'osservatore. Qualcosa di simile

class User 
    attr_accessor :skip_activation 
    #whatever 
end 

Poi, l'osservatore:

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

Non c'è un modo semplice per disattivare gli osservatori, che io sappia, ma sembra possibile aggiungere la logica per il vostro osservatore a non inviare una e-mail quando viene impostato il codice di attivazione ...

2

In generale, per questi tipi di situazioni, è possibile:

  1. Configurare un oggetto fittizio "assorbire" il comportamento indesiderato
  2. Avere una bandiera/switch accessibile dall'esterno che gli osservatori rispetto per inibire il comportamento
  3. Aggiungere logica per l'osservatore a Dete ct quando il comportamento non è necessario in generale (ad es. ciò dbarker suggerisce)
  4. Avere un flag globale "test", "debug", "Avvio" o qualsiasi altra cosa che cambia il comportamento di basso livello
  5. Introspect e rimuovere gli osservatori
  6. Aggiungere un metodo al modello che esegue un'alternativa , versione non osservata dell'attività (condividere l'implementazione con il metodo normale il più possibile).

In questo caso, direi che il 3 è la soluzione migliore.

0

Come altri hanno suggerito; Vorrei avvolgere la logica indesiderata nel tuo Observer con una semplice dichiarazione.

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

Quando i test in esecuzione su un app sto lavorando su, io uso il seguente:

Model.delete_observers 
1

si può prendere il metodo fuori dall'osservatore;

MessageObserver.send(:remove_method, :after_create) 

si fermerà il: after_create il MessageObserver rimuovendolo.

2

Disabilitare osservatori per Rails 3 è semplice:

Rails.configuration.active_record.observers = [] 
6

Un altro si può provare (binari 3)

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

Questo ha completamente risolto il problema per me. Grazie! – Sixty4Bit

+0

questo funziona anche per me !, ma mi piacerebbe aggiungere extra condizionale di ARGV [0] == "db: migrate" perché in futuro potresti scrivere un rake task che utilizza i tuoi osservatori, e potresti dimenticarti su questa piccola piccola linea e tira i tuoi capelli cercando di capire perché i tuoi osservatori non corrono durante il tuo fantastico compito di rake ... –

1

Sono venuto qui in cerca di una risposta alla stessa ... nessuno di quanto sopra sembrava fare il trucco (o comportare l'aggiunta di logica specifica di migrazione al mio codice di applicazione - boo).

Ecco cosa mi è venuta (un po 'zoppo che ha bisogno di andare in ogni migrazione rilevante, ma ...)

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

come bandiera per l'osservatore mi piace definire una funzione di accesso classe chiamata "disabile", così si legge come questo:

class ActivityObserver < ActiveRecord::Observer 
    observe :user 

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

l'ho messo come condizione nelle callback sensibili

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

e devo solo attivare il flag quando necessario

ActivityObserver.disabled=true 
119

Rotaie 3.1 infine dotato di API per questo: 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 

Dove ORM potrebbe per esempio essere ActiveRecord::Base

+0

Questa è di gran lunga la migliore risposta qui :-) –

+0

Nessuno di questi fa lo squat per me. Ho finito per trasformarli in compiti di rake in application.rb – mhenrixon

+1

Cosa userebbe la maggior parte delle persone al posto di 'ORM'? –

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

.... 

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

Altro su questo:

Disabling Callbacks in Rails 3

Problemi correlati