Ruby on rails 在Rails中运行另一个方法之前调用一个方法
我有一个Ruby on rails 在Rails中运行另一个方法之前调用一个方法,ruby-on-rails,callback,observer-pattern,Ruby On Rails,Callback,Observer Pattern,我有一个模型,它有方法1到方法10。我还有ModelObserver。 我想在调用方法1到方法9之前通知ModelObserver,而不是方法10 有没有一种干巴巴的方法来写这篇文章,而不是在所有9种方法中重复notify_observators(:after_something)呢?像这样的方法怎么样 def notify; puts "Was notified."; end def method1; end def method2; end def method3; end def ori
模型
,它有方法1
到方法10
。我还有ModelObserver
。
我想在调用方法1到方法9之前通知ModelObserver
,而不是方法10
有没有一种干巴巴的方法来写这篇文章,而不是在所有9种方法中重复notify_observators(:after_something)呢?像这样的方法怎么样
def notify; puts "Was notified."; end
def method1; end
def method2; end
def method3; end
def original
notify
method1
notify
method2
method3
end
def dry
[:method1, :method2].each do |m|
notify
send(m)
end
method3
end
original
dry
在
config/initializers
directory中添加一个名为monkey\u patches.rb
的文件
class Object
def self.method_hook(*args)
options = args.extract_options!
return unless (options[:before].present? or options[:after].present?)
args.each do |method_name|
old_method = instance_method(method_name) rescue next
define_method(method_name) do |*args|
# invoke before callback
if options[:before].present?
options[:before].is_a?(Proc) ? options[:before].call(method_name, self):
send(options[:before], method_name)
end
# you can modify the code to call after callback
# only when the old method returns true etc..
old_method.bind(self).call(*args)
# invoke after callback
if options[:after].present?
options[:after].is_a?(Proc) ? options[:after].call(method_name, self):
send(options[:after], method_name)
end
end
end
end
end
该补丁允许您在类的实例方法上添加之前
和之后
回调。挂钩可以是:
- 接受一个参数的实例方法的名称
- 接受两个参数的lambda
类模型:更新\u缓存
#lambda作为`before`回调参数
方法:方法1,:方法2,
:before=>lambda{| name,record | p name;p record}
#lambda作为`after`回调参数
方法:方法3,:方法4,
:after=>lambda{| name,record |
Model2.increment\u计数器(:post\u count,record.Model2\u id)}
结束
谢谢您。这是个好主意,但行不通。notify_Observators需要特定于方法1的观察者的方法名称(例如:notify_Observators(:在方法1之后)、notify_Observators(:在方法2之后)。此外,notify语句必须放在方法_1、方法_2等中。非常感谢您提供了一个非常好的答案!回答非常棒。能够轻松地修改钩子定义,以添加我的应用程序所需的其他功能。例如,捕获旧方法
调用的响应,并从新的定义返回它ne_方法
。
class Model < ActiveRecord::Base
def method1
end
def method2
end
def method3
end
def method4
end
def update_cache
end
# instance method name as `after` callback parameter
method_hook :method1, :method2, :after => :update_cache
# lambda as `before` callback parameter
method_hook :method1, :method2,
:before => lambda{|name, record| p name;p record}
# lambda as `after` callback parameter
method_hook :method3, :method4,
:after => lambda{|name, record|
Model2.increment_counter(:post_count, record.model2_id)}
end