40

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

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

谢谢。

4

12 回答 12

122

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

于 2011-12-02T08:01:20.827 回答
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
于 2009-04-02T20:59:12.413 回答
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
于 2011-03-10T14:19:00.337 回答
6

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

config.active_record.observers = :my_model_observer unless File.basename($0) == 'rake'
于 2010-12-04T22:18:11.963 回答
2

一般来说,对于这些情况,您可以:

  1. 设置一个模拟对象来“吸收”不需要的行为
  2. 有一个外部可访问的标志/开关,观察者尊重以抑制行为
  3. 向观察者添加逻辑以检测一般何时不需要该行为(例如 dbarker 建议的内容)
  4. 有一个全局标志“测试”、“调试”、“启动”或任何改变低级行为的东西
  5. 内省并移除观察者
  6. 向您的模型添加一个方法,该方法执行另一个未观察到的任务版本(尽可能与普通方法共享实现)。

在这种情况下,我会说#3 是你最好的选择。

于 2009-04-01T23:43:06.107 回答
2

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

Model.delete_observers
于 2009-04-03T04:35:13.567 回答
2

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

Rails.configuration.active_record.observers = []
于 2010-10-05T10:47:23.540 回答
1

你可以从观察者那里拿掉这个方法;

MessageObserver.send(:remove_method, :after_create)

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

于 2010-02-10T23:24:13.713 回答
1

我来这里是为了寻找相同的答案......以上似乎都没有解决问题(或涉及向我的应用程序代码添加特定于迁移的逻辑——嘘)。

这是我想出的(有点蹩脚,它需要在每个相关的迁移中进行,但是......)

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
于 2011-01-31T19:29:54.123 回答
1
User.skip_callback("create", :after, :send_confirmation_email)

....

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

更多关于这个:

在 Rails 3 中禁用回调

于 2012-12-13T00:40:09.643 回答
0

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

于 2009-04-01T22:59:38.690 回答
0

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

def after_create
  send_email if RAILS_ENV == "production"
end
于 2009-04-02T13:46:48.667 回答