brittohalloran
brittohalloran

Reputation: 3634

Render Different View (template) for ActionMailer

I'm trying to do a conditional render of a different template from ActionMailer (Rails 3.1.1). I want most users to get the normal welcome.html.erb template, but some users to get the special welcome_photographer.html.erb template. This type of thing works in ActionController:

# (in /app/mailers/user_mailer.rb) 
def welcome(user)
  @user = user
  mail(:to => "#{@user.name} <#{@user.email}>", :subject => "Welcome to ...")
  render "welcome_photographer" if @user.is_photographer
end

But the render doesn't work -- everyone gets the standard welcome.html.erb even if @user.is_photographer == true

Upvotes: 41

Views: 17401

Answers (4)

Shahid Ali
Shahid Ali

Reputation: 11

if you are using template_name you also have to pass template_path as an argument where path is the directory name under app/views directory, for example:

class UserMailer < ApplicationMailer
  default from: '[email protected]'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: 'Welcome to My Awesome Site',
         template_path: 'notifications',
         template_name: 'another')
  end
end

Docs link: https://guides.rubyonrails.org/action_mailer_basics.html

Upvotes: 1

Rutger Karlsson
Rutger Karlsson

Reputation: 539

Funny in rails 3.2.14 This does NOT work for me:

mail(:to => "#{@user.name} <#{@user.email}>", :subject => "Welcome to ...") do |format|
  format.html { render 'templatename' }
end

However this does:

mail(:to => "#{@user.name} <#{@user.email}>", 
 :subject => "Welcome to ...", 
:template_name => template)

Upvotes: 10

Malte
Malte

Reputation: 1200

The solution from Sean Hill doesn't work for me (Rails 3.2+). template_name seems to be ignored. What worked for me is something like this:

mail(:to => "#{@user.name} <#{@user.email}>", :subject => "Welcome to ...") do |format|
  format.html { render 'templatename' }
end

Upvotes: 9

Sean Hill
Sean Hill

Reputation: 15056

You shouldn't try to do anything after you call mail(). However, to choose another template, you should pass :template_name as an option. For example:

template = @user.is_photographer ? "welcome_photographer" : "welcome"
mail(:to => "#{@user.name} <#{@user.email}>", 
     :subject => "Welcome to ...", 
     :template_name => template)

Upvotes: 63

Related Questions