Model
はmethod_1
からmethod_10
です。私もModelObserver
を持っています。 method_9
にmethod1を呼び出す前にnotftiy ModelObserver
を入力しますが、method_10
は入力しません。Railsで別のメソッドを実行する前にメソッドを呼び出す
9つのメソッドすべてでnotify_observers(:after_something)を繰り返す代わりに、これを書くDRY方法がありますか?
Model
はmethod_1
からmethod_10
です。私もModelObserver
を持っています。 method_9
にmethod1を呼び出す前にnotftiy ModelObserver
を入力しますが、method_10
は入力しません。Railsで別のメソッドを実行する前にメソッドを呼び出す
9つのメソッドすべてでnotify_observers(:after_something)を繰り返す代わりに、これを書くDRY方法がありますか?
config/initializers
dirctoryでmonkey_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
パッチを使用すると、クラスのインスタンスメソッドにbefore
とafter
コールバックを追加することができます。フックとすることができる:
を受け入れるラムダを受け入れるインスタンスメソッドの名前。フックされるメソッドは、フックの前に来る必要があります。例えば
:
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
どうやってこのようなことができますか?
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
おかげbdon。それはいい考えですが、うまくいかないでしょう。 notify_observersには、notify_observers(:after_method_1)、notify_observers(:after_method_2)など、method1に固有のオブザーバのメソッド名が必要です。さらに、notify文はmethod_1、method_2などに入れなければなりません。 – AdamNYC
回答! – AdamNYC