Rails before_action for ActionMailer that would use mailer arguments

依然范特西╮ 提交于 2019-12-05 03:01:01

ActionMailer uses the AbstractController::Callbacks module. I tried it and it seems to work for me.

The code

class MyMailer < ApplicationMailer
  def process_action(*args)
    # process the args here
    puts args
    super
  end

  def some_mail(*args)
  end
end

MyMailer.some_mail(1, 2) #=> prints ['some_mail', 1, 2]

The documentation


UPDATE

If you're using Rails 5.1, you can have a look at ActionMailer::Parameterized

Solution1:

I would suggest you use this if you do not care about the format

MyMailer.generic("actionx", *mailer_params).deliver_now

def generic(actiontype, *mailer_params)
  # custom logic goes here to construct the to, from, etc.,
  # new_options from custom logic
  self.send(actiontype, new_options)
end

alternative solution below using method_missing from the parent controller

Its not right to put your logic there, but if you still want to do it, you can use the method_missing to put your logic there and skip the action1 and action2 methods.

Original method_missing from action_mailer which can be used as a reference:

def method_missing(method_name, *args)
  if action_methods.include?(method_name.to_s)
    MessageDelivery.new(self, method_name, *args)
  else
    super
  end
end

https://github.com/rails/rails/blob/c8a18aaf44a84f1ef0df007aa3f8446752dc327d/actionmailer/lib/action_mailer/base.rb#L561-L567

Based on Sairam's answer I though of the following but that feels a bit weird, can it not be done with before_action callback ??

class MyMailer < ApplicationMailer

    # Simulation of before_action callback that would support passing the *args to the callback method
    def self.method_missing(method_name, *args)
      method_name = :"#{method_name.to_s}_headers_prefilled"
      if action_methods.include?(method_name)
        mailer = MyMailer.generic(*args) # The before_action callback that passes *args
        mailer.send(method_name, *args) # The action itself
      else
        super
      end
    end

    def generic(*mailer_params)
      # custom logic goes here to construct the headers to, from, etc.,
    end

    def action1_headers_prefilled(mailer_params)
      # Logic only relevant for action1
    end

Also I lose all the cool stuff from before_action (passing an only or except array, etc.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!