Простой способ отключить наблюдателей во время рейк-задачи?
Я использую restful_authentication в своем приложении. Я создаю набор пользователей по умолчанию, используя задачу rake, но каждый раз, когда я запускаю задачу, электронная почта активации отправляется из-за наблюдателя, связанного с моей моделью пользователя. Я устанавливаю поля активации, когда я создаю пользователей, поэтому активация не требуется.
Кто-нибудь знает простой способ обойти наблюдателей во время выполнения рейк-задачи, чтобы никакие электронные письма не отправлялись при сохранении пользователя?
Спасибо.
Ответы
Ответ 1
Вы можете добавить аксессуар в свою модель пользователя, что-то вроде "skip_activation", которое не нужно было бы сохранить, но будет сохраняться через сеанс, а затем проверить флаг в наблюдателе. Что-то вроде
class User
attr_accessor :skip_activation
#whatever
end
Затем в наблюдателе:
def after_save(user)
return if user.skip_activation
#rest of stuff to send email
end
Ответ 2
Rails 3.1, наконец, имеет API для этого:
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
Где ORM
может быть, например, ActiveRecord::Base
Ответ 3
В качестве флага для наблюдателя мне нравится определять аксессуар класса, называемый "отключенным", поэтому он читается следующим образом:
class ActivityObserver < ActiveRecord::Observer
observe :user
# used in tests to disable the observer on demand.
cattr_accessor(:disabled)
end
Я рассматриваю это как условие в чувствительных обратных вызовах
def after_create(record)
return if ActivityObserver.disabled
# do_something
end
и я просто включаю флаг при необходимости
ActivityObserver.disabled=true
Ответ 4
Еще один, который вы можете попробовать (рельсы 3)
config.active_record.observers = :my_model_observer unless File.basename($0) == 'rake'
Ответ 5
В общем, для таких ситуаций вы можете:
- Настройте макет объекта, чтобы "поглотить" нежелательное поведение.
- Имейте внешний доступный флаг/переключатель, который наблюдатели соблюдают, чтобы запретить поведение.
- Добавить логику наблюдателю, чтобы обнаружить, когда поведение вообще не требуется (например, что предлагает dbarker)
- Имейте глобальный флаг "тестирование", "отладка", "запуск" или что-то другое, изменяющее поведение на низком уровне.
- Взгляд и удаление наблюдателей
- Добавьте метод к вашей модели, который выполняет альтернативную, ненаблюдаемую версию задачи (насколько возможно, совместное использование реализации с обычным методом).
В этом случае, я бы сказал, что 3-е место - лучший выбор.
Ответ 6
При выполнении тестов в приложении, над которым я работаю, я использую следующее:
Model.delete_observers
Ответ 7
Отключение наблюдателей для Rails 3 просто:
Rails.configuration.active_record.observers = []
Ответ 8
Вы можете взять метод у наблюдателя;
MessageObserver.send(:remove_method, :after_create)
Остановит: after_create на MessageObserver, удалив его.
Ответ 9
Я пришел сюда, чтобы найти ответ на тот же... Ни один из вышеперечисленных, похоже, не сделал этого трюка (или подразумевал добавление специфичной для миграции логики к моему коду приложения - boo).
Вот что я придумал (немного хромой, что ему нужно идти в каждой соответствующей миграции, но...)
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
Ответ 10
User.skip_callback("create", :after, :send_confirmation_email)
....
User.set_callback("create", :after, :send_confirmation_email)
Подробнее об этом:
Отключение обратных вызовов в Rails 3
Ответ 11
Существует нет простого способа отключить наблюдателей, о которых я знаю, но кажется возможным добавить логику вашему наблюдателю, чтобы не отправлять электронное письмо, когда установлен код активации...
Ответ 12
Как намекают другие; Я бы обернул ненужную логику в Observer с помощью простого оператора if.
def after_create
send_email if RAILS_ENV == "production"
end