Rails before_action for ActionMailer that would use mailer arguments

actionmailer, ruby, ruby-on-rails-5

Solution

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

Problem

Suppose I have a mailer that sends different emails, but is expected to be called with the same parameters. I want to process those parameters for all mailer actions. So, calling a `before_action` that would read the parameters sent to the mailer method ``` /mailers/my_mailer.rb class MyMailer < ApplicationMailer before_filter do |c| # c.prepare_mail # Will fail, because I need to pass `same_param` arguments # # I want to send the original arguments # c.prepare_mail(same_param) # How do I get `same_param` here ? end def action1(same_param) # email view is going to use @to, @from, @context method_only_specific_to_action1 end def action2(same_param) # email view is going to use @to, @from, @context method_only_specific_to_action2 end private def prepare_mail(same_params) @to = same_params.recipient @from = same_params.initiator @context = same_params.context end end ``` Then in my controller/service I do somewhere ``` MyMailer.actionx(*mailer_params).deliver_now ``` How can I access the `same_param` arguments list inside the `before_action` block ? EDIT : I want to refactor from ``` /mailers/my_mailer.rb class MyMailer < ApplicationMailer def action1(same_param) @to = same_params.recipient @from = same_params.initiator @context = same_params.context method_only_specific_to_action1 end def action2(same_param) @to = same_params.recipient @from = same_params.initiator @context = same_params.context method_only_specific_to_action2 end def actionx ... end end ``` And this refactoring ``` /mailers/my_mailer.rb class MyMailer < ApplicationMailer def action1(same_param) prepare_mail(same_params) method_only_specific_to_action1 end def action2(same_param) prepare_mail(same_params) method_only_specific_to_action2 end def actionx ... end private def prepare_mail(same_params) @to = same_params.recipient @from = same_params.initiator @context = same_params.context end end ``` Feels non-optimal (`prepare_mail(same_params)` duplicated in every action) Hence what was suggested above

Original source