Altcademy - a Forbes magazine logo Best Coding Bootcamp 2023

What is Mailer in Ruby on Rails?

Mailer in Ruby on Rails is a powerful feature that allows developers to send emails from their applications. As developers, we often need to send emails for various reasons, like sending welcome emails to new users, password reset emails, or even notifications for certain events. In this blog post, we will explore the concepts of Mailers in Rails and understand how to use them effectively.

If you are new to programming or just starting with Ruby on Rails, don't worry! We will try to explain the concepts in a simple way and avoid using jargons as much as possible. And if we use any, we will make sure to explain them in detail. Let's get started!

What is a Mailer?

A Mailer in Ruby on Rails can be thought of as a "post office" that sends out emails. It is a special kind of class that inherits from ActionMailer::Base, which provides the necessary methods and structure to send emails using Rails.

In a nutshell, a Mailer is responsible for the following tasks:

  • Defining email methods that set up the email properties, like the recipient, subject, and content.
  • Rendering the email views (templates) that contain the actual content of the emails.
  • Sending the emails using the email delivery configuration defined in the Rails application.

Now that we have a basic understanding of Mailers in Rails, let's see how to create and use one in our application.

Creating a Mailer

In Rails, we can create a new Mailer using the rails generate mailer command. Let's create a UserMailer that will be responsible for sending emails related to user accounts:

rails generate mailer UserMailer

This command will generate the following files:

  • app/mailers/user_mailer.rb: The Mailer class file.
  • app/views/user_mailer/: The directory where email templates will be stored.
  • test/mailers/user_mailer_test.rb: The test file for the Mailer (if you use TestUnit).
  • test/mailers/previews/user_mailer_preview.rb: The preview file for the Mailer, allowing you to preview emails in the browser during development.

Now that we have the basic structure for our Mailer, let's define an email method that sends a welcome email to new users.

Defining an Email Method

In the UserMailer class (app/mailers/user_mailer.rb), we will define a method called welcome_email. This method will set up the email properties like the recipient and subject.

class UserMailer < ActionMailer::Base
  default from: 'noreply@example.com'

  def welcome_email(user)
    @user = user
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end
end

In this code snippet, we define a welcome_email method that takes a user as an argument. We set the @user instance variable to be used in the email template later. The mail method is called with the recipient's email address and a subject for the email.

The default from: 'noreply@example.com' line sets the default sender email address for all emails sent by this Mailer. You can replace this with your own email address or use a custom domain if you have one.

Now that we have our email method set up, let's create an email template that contains the content of the welcome email.

Creating an Email Template

Email templates in Rails are just like view templates, where we can use HTML and embedded Ruby (ERB) to create dynamic content. By default, Rails supports two formats for email templates: HTML and plain text.

Let's create an HTML template for our welcome_email method. Create a new file called welcome_email.html.erb inside the app/views/user_mailer/ directory and add the following content:

<!DOCTYPE html>
<html>
<head>
  <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
  <h1>Welcome to My Awesome Site, <%= @user.name %>!</h1>
  <p>
    We are excited to have you on board. To get started, please click the link below to confirm your email address:
  </p>
  <%= link_to 'Confirm Email', confirm_email_url(@user.confirmation_token) %>
</body>
</html>

In this template, we use the @user instance variable that we set in the welcome_email method to display the user's name. We also use the link_to helper to generate a confirmation URL for the user. The confirm_email_url should be a URL helper for a route in your application that handles email confirmation.

Now that we have our email method and template ready, let's see how to send the welcome email when a new user is created.

Sending Emails

To send the welcome email, we need to call the welcome_email method from the UserMailer whenever a new user is created. We can do this in the controller or a model callback, depending on how you handle user registration in your application.

For example, if you are using the create action in your UsersController, you can add the following line after the user is saved:

def create
  @user = User.new(user_params)

  if @user.save
    # Send the welcome email
    UserMailer.welcome_email(@user).deliver_now

    # Redirect to the homepage or another page
    redirect_to root_url, notice: 'Thank you for signing up!'
  else
    render :new
  end
end

Here, we call the welcome_email method with the newly created user and use the deliver_now method to send the email immediately. Alternatively, you can use the deliver_later method to send the email asynchronously using a background job.

That's it! Now, whenever a new user is created, they will receive a welcome email with a confirmation link.

Testing and Previewing Emails

It's essential to test and preview your emails during development to ensure they look and work as expected. Rails provides a built-in way to preview emails in the browser using the Mailer Preview feature.

To create a preview for our welcome_email, open the user_mailer_preview.rb file inside the test/mailers/previews/ directory and add the following code:

class UserMailerPreview < ActionMailer::Preview
  def welcome_email
    user = User.new(name: 'John Doe', email: 'john.doe@example.com', confirmation_token: '123456')
    UserMailer.welcome_email(user)
  end
end

In this code snippet, we define a welcome_email preview method that creates a sample user and calls the welcome_email method from the UserMailer. Now, you can preview the welcome email in your browser by navigating to /rails/mailers/user_mailer/welcome_email.

Make sure to test your emails in different email clients and devices to ensure compatibility and a consistent user experience.

Configuring Email Delivery

By default, Rails uses the :smtp delivery method to send emails. You will need to configure the SMTP settings for your email provider in the config/environment.rb or the specific environment configuration file (e.g., config/environments/production.rb). Here's an example configuration for Gmail:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.gmail.com',
  port: 587,
  domain: 'example.com',
  user_name: ENV['GMAIL_USERNAME'],
  password: ENV['GMAIL_PASSWORD'],
  authentication: 'plain',
  enable_starttls_auto: true
}

Replace the domain, user_name, and password settings with your own values. You can also use environment variables to keep sensitive information like email credentials out of your codebase.

Make sure to configure the default_url_options for your application, especially in the production environment, to generate correct URLs in your emails:

config.action_mailer.default_url_options = { host: 'yourwebsite.com' }

Conclusion

In this blog post, we learned about Mailers in Ruby on Rails and how to use them to send emails from our applications. We covered creating a Mailer, defining email methods, creating email templates, sending emails, and configuring email delivery.

By using Mailers in Rails, you can enhance the user experience of your application and provide essential features like email confirmations, password resets, and notifications. Make sure to test and preview your emails to ensure a consistent and professional look across different email clients and devices.

Keep learning and happy coding!