【发布时间】:2011-07-01 05:18:19
【问题描述】:
我对一个问题感到绝望。
我想注册自定义回调:after_something 然后将该回调用于观察者。
我曾尝试使用 define_callbacks、set_callbacks 但观察者从未触发该回调。
我知道我可以使用 AR 回调,但我只是更喜欢在某些情况下使用我自己的回调。
谢谢
【问题讨论】:
标签: ruby-on-rails callback observer-pattern
我对一个问题感到绝望。
我想注册自定义回调:after_something 然后将该回调用于观察者。
我曾尝试使用 define_callbacks、set_callbacks 但观察者从未触发该回调。
我知道我可以使用 AR 回调,但我只是更喜欢在某些情况下使用我自己的回调。
谢谢
【问题讨论】:
标签: ruby-on-rails callback observer-pattern
Observer 使用标准 AR 回调,因此它不会触发您的默认回调。
我认为不如发明新的回调(以及 AR 的猴子补丁默认行为),也许您应该使用 AR。很难说你想要什么。能给个用例吗?
试试看
before_save MyCallbacks.new, :if => :some_condiditons_meet?
class MyCallbacks
def before_save(object)
sophistcated_use(object) if object.valid?
damn_have_it?
end
end
它实际上在某种程度上涵盖了观察者的行为
保存、保存!或销毁调用的整个回调链在事务中运行。这包括 after_* 钩子。如果一切顺利,则在链完成后执行 COMMIT。
我认为单一观察者的整个想法并不是最好的解决方案。在更多依赖项到达后,您的逻辑将非常复杂。定义自己的事务包装器很好,但你真的需要它吗?也许您可以重新安排模型来实现它,而无需编写自己的交易案例。
例如
class Friendship < ActiveRecord::Base
belongs_to :user
has_many :users, :through => :groups
after_validation :save_my_records
def save_my_records
user.friend.history.save
user.history.save
end
end
朋友是对象 => 有自己的观察者 历史是对象 => 有自己的观察者
它非常抽象,但是如果没有你的代码,我不知道如何给出一些建设性的例子,而且 after_validation 也不是保存我认为的任何东西的最佳位置。
notify_observer 对我来说听起来也像 hack :-)
【讨论】:
如果有人在寻找以下解决方案:
在你的模型中调用这个:
notify_observers(:after_my_custom_callback)
在你的观察者中定义方法:
def after_my_custom_callback(record)
#do things
end
【讨论】:
notify 更改为 notify_observers
感谢 Alex 的回答,我可以通过定义应调用的 define_model_callbacks_for_observers 方法而不是 define_model_callbacks 来解决此问题(您可能希望将其放入模块中):
def define_model_callbacks_for_observers(*args)
types = Array.wrap(args.extract_options![:only] || [:before, :around, :after])
callbacks = define_model_callbacks(*args)
callbacks.each do |callback|
types.each do |filter|
set_callback(callback, filter) do
notify_observers :"#{filter}_#{callback}"
true
end
end
end
end
【讨论】: