为多个模型动态实例化 ActiveRecord Observer

发布于 2024-10-07 07:15:57 字数 1033 浏览 10 评论 0原文

我目前正在尝试开发一个观察多个模型的插件/gem。理想情况下,观察者应该仅使用一个单例方法自动实例化...

class MyModel < ActiveRecord::Base

  # a class method like this will tell the observer to observe this model
    observe_me

end

我最初的方法是定义包含在 AR 基础中的类方法:

module ClassMethods

  def observe_me
    @observe_me = true
  end

  def should_observe_me?
    @observe_me
  end
end
ActiveRecord::Base.extend(ClassMethods)

然后使用它来检测观察者中要观察的模型:

class MyObserver < ActiveRecord::Observer

  # this should observe all models where should_observe_me? #=> true
  observe ActiveRecord::Base.descendants.select { |m| m.try(:should_observe_me?) }.map(&:model_name)

end

我正在运行的问题into 是在定义模型之前加载观察者,因此 ActiveRecord 没有后代,并且 MyObserver 不知道要观察哪些模型。

我的下一次尝试是使用 ActiveRecord::Base.observers 和 ActiveRecord::Base.instantiate_observers 进行破解,但没有成功。

因此,目前的情况是:

观察者已定义,但不知道要观察哪些模型。 模型被定义并将其自身标记为待观察,但观察者已被观察。

有没有办法可以延迟观察者的加载,直到定义模型之后,或者有人可以想出更好的方法来解决这个问题?

I'm trying to develop a plugin/gem at the moment which observes multiple models. Ideally, the observer should be instantiated automatically with just one singleton method...

class MyModel < ActiveRecord::Base

  # a class method like this will tell the observer to observe this model
    observe_me

end

My initial approach was to define class methods included into AR base:

module ClassMethods

  def observe_me
    @observe_me = true
  end

  def should_observe_me?
    @observe_me
  end
end
ActiveRecord::Base.extend(ClassMethods)

And then use this to detect which models to observe within the Observer:

class MyObserver < ActiveRecord::Observer

  # this should observe all models where should_observe_me? #=> true
  observe ActiveRecord::Base.descendants.select { |m| m.try(:should_observe_me?) }.map(&:model_name)

end

The problem that I'm running into is that the observer is being loaded before the models are defined, so ActiveRecord has no descendants and MyObserver doesn't know which models to observe.

My next attempt was to hack around with ActiveRecord::Base.observers and ActiveRecord::Base.instantiate_observers but with no luck.

So, as it is at the moment:

Observer is defined but doesn't know which models to observe.
Models are defined and flag themselves to be observed but the observer has already been observed.

Is there a way I can delay the loading of the observer until after the models are defined or can someone think of a better approach to this problem?

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

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

发布评论

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

评论(1

瑾夏年华 2024-10-14 07:15:57

@gavin:Rails3 中应用程序初始化的结构已更改 - 这可能是您的问题。

您何时/如何包含 ClassMethods 模块?如果您在 Rails3 中,并且如果您将“require 'observe_me'”添加到 $ROOT/config/environment.rb,那么您会看到您所描述的(错误)行为。

如果是这样,请创建 $ROOT/config/initializers/my_extensions.rb 并将“require ...”粘贴在那里。

@gavin: The structure of the application initialization has changed in Rails3 -- this might be your problem.

When / how are you including the ClassMethods module? IF you are in Rails3, and IF you added "require 'observe_me'" to $ROOT/config/environment.rb, then you'd see the (mis)behavior you describe.

If so, instead, create $ROOT/config/initializers/my_extensions.rb and stick the "require ..." in there.

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