ActionMailerの個別のクラスで、interceptorみたいなことをやりたい
ActionMailerにはinterceptorという機能があって、メールを送信するときにいろいろと処理を挟むことができます。
class TsukaInterceptor  
  def self.delivering_email(message)  
    message.title = "[development] #{message.title}"  
  end  
end  
みたいなクラスを作っておいて、initializerなどで
ActionMailer::Base.register_interceptor(TsukaInterceptor) if Rails.env.development?  
とやっておけば、development環境で送信するメールのサブジェクトには、すべて [development] がつくようになります。
interceptorクラスのクラスメソッド delivering_email に渡される引数 message は、Mail::Messageクラスのオブジェクトです。
というようにinterceptorはとても便利なのですが、ActionMailer全体に影響してしまうので、個別のActionMailerクラスで別のことをやりたいときに困ります。
たとえば、あるActionMailerクラスを使ってdevelopment環境からメール送信をするときだけ、メールのあて先を変更したいとき。
interceptorを使っちゃうと全部のMailerに影響してしまうし、inteceptorクラスのdelivering_emailメソッド内で切り分けようとしても、Mail::MessageオブジェクトからはActionMailer::Baseクラスはわからないのです。
どうしようかなとちょっと悩んでtwitterでつぶやいたら、1分後くらいに元同僚のK和さんが「AbstractController::Callbacksを使ったらいいですよ」と教えてくれました。
さっそくやってみます。
class TsukaMailer < ActionMailer::Base  
  if Rails.env.development?  
    include AbstractController::Callbacks  
    after_filter :check_to  
    def check_to  
      message.to = "tsuka@example.com"  
    end  
    private :check_to  
  end  
  def hoge  
   ...  
  end  
end  
としたら、development環境のときだけ、メールのあて先がすべて check_to メソッドの中で指定したものに変わりました。
message というのは、Mail::Messageオブジェクトで、以下のように attr_internal 宣言されているのでこういうふうにアクセスできます。
https://github.com/rails/rails/blob/4-1-stable/actionmailer/lib/action_mailer/base.rb#L558
