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
ApplicationMailer
is likeActionMailer::Base
. In my previous comment I was just explaining I'm not just sending mails directly via SMTP but also configuring to use:file
,:cache
,:letter_opener
, etc delivery adapters which are wrapped nicely by ActionMailer – Antipopeprepare_mail
I am just setting instance variables that will be directly used in an ActionMailer's view. I would have to pass too many parameters otherwise – Antipopebefore_action
filter I can do something likec.prepare_mail(*arguments_sent_to_mailer_action)
. I just edited, hope it's clearer – Antipopebefore_action
is defined inAbstractController::Callbacks
. This method doesn't exist in the context of a Mailer. If you really want to use callbacks in the context of an Mailer than you need to implement the logic to use them. You might want to have a look intoActiveSupport::Callbacks
. – MuirheadCallbacks in Action Mailer are implemented using AbstractController::Callbacks
(at least in Rails 4-5, yes I know it's weird they didn't refactor that name) andbefore_action
DOES work. api.rubyonrails.org/classes/ActionMailer/Base.html – Antipope