在耙子任务期间关闭观察员的简单方法?

时间:2009-04-01 22:36:39

标签: ruby-on-rails ruby observer-pattern restful-authentication

我在我的应用中使用restful_authentication。我正在使用rake任务创建一组默认用户,但每次运行任务时都会因为与我的用户模型关联的观察者而发送激活电子邮件。我在创建用户时设置激活字段,因此不需要激活。

任何人都知道在运行rake任务时绕过观察者的简单方法,以便在我保存用户时不会发送电子邮件?

感谢。

12 个答案:

答案 0 :(得分:120)

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

答案 1 :(得分:8)

您可以为您的用户模型添加一个访问者,例如“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 :(得分:8)

作为观察者的标志,我喜欢定义一个名为“disabled”的类访问器,所以它的内容如下:

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

答案 3 :(得分:6)

你可以尝试的另一个(rails 3)

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

答案 4 :(得分:2)

通常,对于这些情况,您可以:

  1. 设置模拟对象以“吸收”不需要的行为
  2. 有一个外部可访问的标志/开关,观察者会尊重这种行为
  3. 向观察者添加逻辑以检测行为何时不需要一般(例如dbarker建议的那样)
  4. 拥有全局标志“测试”,“调试”,“启动”或任何改变低级别行为的内容
  5. 反思并删除观察员
  6. 向您的模型添加一个方法,该方法执行任务的替代的,未观察到的版本(尽可能使用常规方法共享实现)。
  7. 在这种情况下,我会说#3是你最好的选择。

答案 5 :(得分:2)

在我正在处理的应用程序上运行测试时,我使用以下内容:

Model.delete_observers

答案 6 :(得分:2)

禁用Rails 3的观察者很简单:

Rails.configuration.active_record.observers = []

答案 7 :(得分:1)

你可以从观察者那里取出这个方法;

MessageObserver.send(:remove_method, :after_create)

通过删除它来停止MessageObserver上的:after_create。

答案 8 :(得分:1)

我来到这里寻找相同的答案......上面没有一个似乎可以解决问题(或者涉及在我的应用程序代码中添加特定于迁移的逻辑 - 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

答案 9 :(得分:1)

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

....

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

更多相关内容:

Disabling Callbacks in Rails 3

答案 10 :(得分:0)

没有一种简单的方法可以禁用我所知道的观察者,但是听起来可以向观察者添加逻辑,以便在设置激活码时不发送电子邮件...

答案 11 :(得分:0)

正如其他人暗示的那样;我将使用简单的if语句将不需要的逻辑包装在Observer中。

def after_create
  send_email if RAILS_ENV == "production"
end