In this article, we’ll take a look at one of the lesser-known features within Action Mailer, that is specifying a template and a layout through the mail function. This can come in handy if we want to display specific content for certain emails without creating unnecessary mailers. 🧠

Specifying a template

There are a few ways to specify a template through the mail function. The mail function accepts keyword arguments called template_path and template_name.

template_path

template_path is for telling Action Mailer which folder to use to look for a template. template_path can either be a string or an array. Action Mailer will start looking for the specified template_path from within app/views folder. Let’s say, our template_path is set to invitations. Then, Action Mailer will look for app/views/invitations folder.

template_name

template_name is for telling Action Mailer the name of the template that we want to use.

Examples

The first example here shows how we can use a template called welcome that sits inside of app/views/mailers/user_mailer/special folder. The template_path here is a string.

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(to: email, template_path: 'mailers/user_mailer/special')
  end
end

The second example here is similar to the above, but template_path is an array. It’s an array of path to folders. Action Mailer will look for the welcome template by starting on the first folder, app/views/mailers/user_mailer/non-special. If the template is not found, Action Mailer will move onto the next folder, app/views/mailers/user_mailer/special, which is where our template sits. Here, Action Mailer will stop looking for the template folder and send the email.

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(
      to: email,
      template_path: ['mailers/user_mailer/non-special', 'mailers/user_mailer/special', 'mailers']
    )
  end
end

The third example here shows how we can use a template called special_welcome instead of welcome. special_welcome sits inside of app/views/mailers/user_mailer folder

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(to: email, template_name: 'special_welcome')
  end
end

The fourth example here shows that we can specify both template_name and template_path! This will look for a template called special_welcome inside of app/views/mailers/user_mailer/international_launch folder.

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(
      to: email,
      template_name: 'special_welcome',
      template_path: 'mailers/user_mailer/international_launch'
    )
  end
end

The fifth and last example here shows that we can specify the name and location of the template by passing a block to the mail function. Within the block, we can determine what to render for html, which is basically the content of the email.
One of the keyword arguments accepted by render is template.

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(to: email) do |format|
      format.html do
        render template: 'mailers/user_mailer/international_launch/special-welcome'
      end
    end
  end
end

Specifying a Layout

Another keyword argument accepted by render is layout.

Example

The example here shows how we can use a layout called yet-another-layout. Action Mailer will look for the layout from within app/layouts folder.

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(to: email) do |format|
      format.html { render layout: 'yet-another-layout' }
    end
  end
end

Specifying both the layout and template at once

Yup! We can specify both of them. 😉

Example

The example here will use a layout called yet-another-layout in app/layouts folder and a template called yet-another-template in app/views/mailers folder.

class UserMailer < ApplicationMailer
  def welcome(user)
    email = user.email

    mail(to: email) do |format|
      format.html do
        render layout: 'yet-another-layout', template: 'mailers/yet-another-template'
      end
    end
  end
end


Cheers for reading! 🤓