Ada*_*NYC 4 ruby-on-rails observer-pattern
我在帐户模型中有几种方法:支付,接收,退款等我希望我的AccountObserver观看.但我想将额外的对象传递给我的AccountObserver.
例如,在我的帐户模型中,我想定义:
def pay
...
notify_observers(:after_pay, payee, amount)
end
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
谢谢.
不要覆盖notify_observers.修补核心类是一个非常糟糕的主意.相反,你应该做的是:
不要在模型上调用仅限于方法名称的实例方法,而是自己调用类方法:
# Notify list of observers of a change.
def notify_observers(*arg)
observer_instances.each { |observer| observer.update(*arg) }
end
Run Code Online (Sandbox Code Playgroud)
它将您提供给它的任何参数传递给观察者的#update方法,您可以在自己的观察者类中覆盖它.
默认值不接受任何无关的参数,但不是太复杂:
def update(observed_method, object, &block) #:nodoc:
return unless respond_to?(observed_method)
return if disabled_for?(object)
send(observed_method, object, &block)
end
Run Code Online (Sandbox Code Playgroud)
所以只需将其添加到您的观察者,例如:
def update(observed_method, object, *args)
return unless respond_to?(observed_method)
return if disabled_for?(object)
send(observed_method, object, *args)
end
def after_pay(payee, amount)
...
end
Run Code Online (Sandbox Code Playgroud)
并致电
Payee.notify_observers(:after_pay, payee, amount)
Run Code Online (Sandbox Code Playgroud)
恐怕这对于观察者来说不是一个很好的用例。我能想到的最好的方法是在您的 Account 对象上设置一个实例变量,然后您可以在观察者中访问该实例变量,而无需完全采用不同的路线,例如:
class Account < ActiveRecord::Base
attr_reader :last_payment
def pay payee, amt
@last_payment = [ payee, amt ]
notify_observers :after_pay
end
end
class AccountObserver < ActiveRecord::Observer
def after_pay account
payee, amt = account.last_payment
Rails.logger.info "#{payee} paid #{amt}!"
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1586 次 |
| 最近记录: |