在 rake 任务期间关闭观察者的简单方法?

发布于 2024-07-15 17:59:58 字数 199 浏览 4 评论 0原文

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

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

谢谢。

I'm using restful_authentication in my app. I'm creating a set of default users using a rake task, but every time I run the task an activation email is sent out because of the observer associated with my user model. I'm setting the activation fields when I create the users, so no activation is necessary.

Anyone know of an easy way to bypass observers while running a rake task so that no emails get sent out when I save the user?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

紅太極 2024-07-22 17:59:58

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

Rails 3.1 finally comes with API for this:
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

Where ORM could for example be ActiveRecord::Base

铃予 2024-07-22 17:59:58

作为观察者的标志,我喜欢定义一个名为“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

As a flag for the observer I like to define a class accessor called "disabled" so it reads like this:

class ActivityObserver < ActiveRecord::Observer
  observe :user

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

I put it as a condition in the sensitive callbacks

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

and I just turn the flag on when needed

ActivityObserver.disabled=true
吃颗糖壮壮胆 2024-07-22 17:59:58

您可以向用户模型添加一个访问器,例如“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

You could add an accessor to your user model, something like "skip_activation" that wouldn't need to be saved, but would persist through the session, and then check the flag in the observer. Something like

class User
  attr_accessor :skip_activation
  #whatever
end

Then, in the observer:

def after_save(user)
  return if user.skip_activation
  #rest of stuff to send email
end
初熏 2024-07-22 17:59:58

您可以尝试另一种(rails 3)

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

Another one you can try (rails 3)

config.active_record.observers = :my_model_observer unless File.basename($0) == 'rake'
断爱 2024-07-22 17:59:58

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

  1. 设置一个模拟对象来“吸收”不需要的行为
  2. 有一个观察者遵守的外部可访问标志/开关来抑制行为
  3. 向观察者添加逻辑以检测行为何时发生一般来说不需要(例如 dbarker 建议的)
  4. 有一个全局标志“testing”、“debug”、“startup”或任何改变低级行为的标志
  5. 内省并删除观察者
  6. 在模型中添加一个方法执行任务的替代的、不可观察的版本(尽可能与普通方法共享实现)。

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

In generally, for these sorts of situations, you can:

  1. Set up a mock object to "absorb" the unwanted behavior
  2. Have an externally accessible flag / switch that the observers respect to inhibit the behavior
  3. Add logic to the observer to detect when the behavior is unneeded in general (e.g. what dbarker suggests)
  4. Have a global flag "testing", "debug", "startup" or whatever that changes low level behavior
  5. Introspect and remove the observers
  6. Add a method to your model that performs an alternative, unobserved version of the task (sharing implementation with the normal method as much as possible).

In this case, I'd say #3 is your best bet.

街角迷惘 2024-07-22 17:59:58

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

Model.delete_observers

When running tests on an app I am working on, I use the following:

Model.delete_observers
小糖芽 2024-07-22 17:59:58

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

Rails.configuration.active_record.observers = []

Disabling observers for Rails 3 it's simple:

Rails.configuration.active_record.observers = []
烟酒忠诚 2024-07-22 17:59:58

你可以把这个方法从观察者身上拿走;

MessageObserver.send(:remove_method, :after_create)

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

You can take the method off the observer;

MessageObserver.send(:remove_method, :after_create)

Will stop the :after_create on MessageObserver by removing it.

音栖息无 2024-07-22 17:59:58

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

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

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

I came here looking for the an answer to the same... none of the above seemed to do the trick (or involve adding migration-specific logic to my application code -- boo).

Here's what I came up with (a bit lame that it needs to go in each relevant migration, but...)

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
一枫情书 2024-07-22 17:59:58
User.skip_callback("create", :after, :send_confirmation_email)

....

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

更多相关内容:

禁用 Rails 3 中的回调

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

....

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

More on this:

Disabling Callbacks in Rails 3

嗫嚅 2024-07-22 17:59:58

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

There isn't a straightforward way to disable observers that I know of, but it sounds possible to add logic to your observer to not send an email when the activation code is set...

淡水深流 2024-07-22 17:59:58

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

def after_create
  send_email if RAILS_ENV == "production"
end

As others have hinted; I would wrap the unwanted logic in your Observer with a simple if statement.

def after_create
  send_email if RAILS_ENV == "production"
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文