# frozen_string_literal: truemoduleActionMailer# = Action Mailer \Parameterized## Provides the option to parameterize mailers in order to share instance variable# setup, processing, and common headers.## Consider this example that does not use parameterization:## class InvitationsMailer < ApplicationMailer# def account_invitation(inviter, invitee)# @account = inviter.account# @inviter = inviter# @invitee = invitee## subject = "#{@inviter.name} invited you to their Basecamp (#{@account.name})"## mail \# subject: subject,# to: invitee.email_address,# from: common_address(inviter),# reply_to: inviter.email_address_with_name# end## def project_invitation(project, inviter, invitee)# @account = inviter.account# @project = project# @inviter = inviter# @invitee = invitee# @summarizer = ProjectInvitationSummarizer.new(@project.bucket)## subject = "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"## mail \# subject: subject,# to: invitee.email_address,# from: common_address(inviter),# reply_to: inviter.email_address_with_name# end## def bulk_project_invitation(projects, inviter, invitee)# @account = inviter.account# @projects = projects.sort_by(&:name)# @inviter = inviter# @invitee = invitee## subject = "#{@inviter.name.familiar} added you to some new stuff in Basecamp (#{@account.name})"## mail \# subject: subject,# to: invitee.email_address,# from: common_address(inviter),# reply_to: inviter.email_address_with_name# end# end## InvitationsMailer.account_invitation(person_a, person_b).deliver_later## Using parameterized mailers, this can be rewritten as:## class InvitationsMailer < ApplicationMailer# before_action { @inviter, @invitee = params[:inviter], params[:invitee] }# before_action { @account = params[:inviter].account }## default to: -> { @invitee.email_address },# from: -> { common_address(@inviter) },# reply_to: -> { @inviter.email_address_with_name }## def account_invitation# mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"# end## def project_invitation# @project = params[:project]# @summarizer = ProjectInvitationSummarizer.new(@project.bucket)## mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"# end## def bulk_project_invitation# @projects = params[:projects].sort_by(&:name)## mail subject: "#{@inviter.name.familiar} added you to some new stuff in Basecamp (#{@account.name})"# end# end## InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_latermoduleParameterizedextendActiveSupport::Concernincludeddoattr_writer:paramsdefparams@params||={}endendmoduleClassMethods# Provide the parameters to the mailer in order to use them in the instance methods and callbacks.## InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later## See Parameterized documentation for full example.defwith(params)ActionMailer::Parameterized::Mailer.new(self,params)endendclassMailer# :nodoc:definitialize(mailer,params)@mailer,@params=mailer,paramsendprivatedefmethod_missing(method_name,...)if@mailer.action_methods.include?(method_name.name)ActionMailer::Parameterized::MessageDelivery.new(@mailer,method_name,@params,...)elsesuperendenddefrespond_to_missing?(method,include_all=false)@mailer.respond_to?(method,include_all)endendclassMessageDelivery<ActionMailer::MessageDelivery# :nodoc:definitialize(mailer_class,action,params,...)super(mailer_class,action,...)@params=paramsendprivatedefprocessed_mailer@processed_mailer||=@mailer_class.new.tapdo|mailer|mailer.params=@paramsmailer.process@action,*@argsendenddefenqueue_delivery(delivery_method,options={})ifprocessed?superelse@mailer_class.delivery_job.set(options).perform_later(@mailer_class.name,@action.to_s,delivery_method.to_s,params: @params,args: @args)endendendendend