ActionMailer pass local variables to the erb template
Solution 1
All options available in the mail
method can be found at http://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-mail.
We know that render
has a :locals
option. However we can see that there is no :locals
option available for mail
. Therefore, no, there is no better way than to use instance variables (unless you want to use something hideous like globals or persistent database objects - don't do this).
Instance variables are what you are meant to use.
Solution 2
As ronalchn pointed out, it's the render
that has :locals
, not the mail
method. So, you need a direct access to the render
method in order to pass the locals.
You can give a block to the mail
and that way gain access to the render
method, something like this:
mail(to: "[email protected]", subject: "Test passing locals to view from mailer") do |format|
format.html {
render locals: { recipient_name: "John D." }
}
end
And now you should be able to use "Hello <%= recipient_name %>"
Solution 3
In Rails 5, you simply have to define instance variables using @
in your method. You no longer have access to the locals
property for this purpose.
class UserMailer < ApplicationMailer
def welcome_email(user_id:, to_email:, user_full_name:, token:)
# Mail template variables
@user = User.find_by(id: user_id)
@token = token
mail(:to => to_email,
:subject => MAILER_SUBJECTS_WELCOME,
:template_path => "user_mailer",
:template_name => "welcome_email")
end
end
Then you can just access them in your email template using <%= @user %>
and <%= @token %>
Related videos on Youtube
Dmitri
Updated on June 24, 2022Comments
-
Dmitri almost 2 years
I know I could define instance variables e.g:
def user_register(username, email) @username = username @email = email mail(:to => email, :subject => "Welcome!", :template_name => "reg_#{I18n.locale}") end
But, is there a way to use local variables instead, just like passing :locals to partials?
-
Dmitri over 9 yearsThank you, @rap1ds I will try that approach :)
-
Leo Lei about 6 yearsThis has always been the case even prior to Rails 5.