更新されたソリューション
全体的に、解決策は非常に簡単です。オブジェクト(など)でdelayed_jobを実行している場合は、MyClass.new.delay.some_method
エラー処理をオブジェクトメソッドとして定義する必要があります。(のような)クラスでdelayed_jobを実行している場合はMyTestMailer.test_email ...
、エラー処理をクラスメソッドとして定義する必要があります。
と呼ばれるメーラーがあるとしましょうTestMailer
。解決策は、エラー処理をオブジェクトメソッドではなくクラスメソッドとして定義することです。
# Your rails mailer
class TestMailer
# Whoa! error has to be a class method!
def self.error(job, e)
puts "I can now handle test mailer errors in delayed job!!!!"
end
end
これで、上記のdef self.error
メソッドが遅延ジョブのエラーコールバックとして使用されます。
または、すべてのアクションメーラーエラーを処理できるようにしたい場合は、
class ActionMailer::Base
def self.error(job, e)
puts "I can now handle all mailer errors in delayed job!!!"
end
end
その理由は、DelayedJobの内部PerformableMethod
がエラーを処理する方法が原因です。APerformableMethod
には、ターゲットオブジェクトとターゲットメソッドの2つがあります。Action Mailerの場合、ターゲットオブジェクトはオブジェクトではなく、メーラークラスTestMailer
です。ターゲットメソッドは、使用するメールメソッドですtest_mail
。DelayedJobは、ターゲットオブジェクト上のすべてのフック(、、、など)をerror
検索します。しかし、私たちの場合、ターゲットオブジェクトはクラス自体です。したがって、フックはクラスメソッドとして定義する必要があります。before
after
ActionMailerメールを処理する方法DelayedJob
は少しハッキーです。クラスメソッドの代わりにオブジェクトメソッドを追加すると、不要な例外がスローされます。たとえば、コードは次のとおりです。
# In <delayed-job-gem>/lib/delayed/performable_method.rb
module Delayed
class PerformableMethod
# line #7
delegate :method, :to => :object
rubyのすべてのオブジェクトには、method
そのクラス内のメソッドへの生の参照を取得するために使用される関数があります。しかし、DelayedJobでは、このrawmethod
関数は他のターゲットオブジェクトに委任されています。このハックにより、def error
ジョブエラーを処理するための関数を通常は使用できなくなります。
編集:脚注を追加、マイナーな説明
編集2:並べ替えられた回答