Ruby on Rails ActionMailer to Send Emails
Overview
Communication with the users is essential for any web application. Without delivering feedback to end users, an application is incomplete, and email is one of the most efficient ways to do it. Ruby on Rails ActionMailer is a strong tool for sending emails from Rails apps.
Rails ActionMailer allows developers to easily send emails with attachments in plain text, HTML, or both. Emails can be sent from anywhere within the application, making it easy to integrate.
This article will go over Rails ActionMailer, its functionality, and how to send emails using it. The methods, views, layouts, setup, and callbacks of the Rails ActionMailer will also be covered.
What is Rails ActionMailer?
Rails ActionMailer is a framework that allows developers to create and send emails from their Rails applications. It offers a simple and organized method for producing emails and managing email templates. Mailers are created as subclasses of ActionMailer::Base.
Rails Mailers work in a similar way to controllers, with actions corresponding to email messages that need to be sent. These actions have associated views that create the content of the email and can use instance variables and layouts. Mailers also have access to a params hash to pass data to email views. Once the email messages are generated, they can be delivered using a variety of email delivery mechanisms.
ActionMailer for Sending Mail
Rails ActionMailer makes sending emails from the Rails application simple. The library includes a set of classes and methods for creating, sending, and managing emails.
We must first develop a rails mailer class in order to use ActionMailer. The mailer class defines email templates, email sending mechanisms, and any other configuration parameters.
Generating Mailer
To set up a mailer in Ruby on Rails, we need to follow the steps given below:
Creating the Mailer
Run the following command in the terminal to create a new mailer:
This command will generate a new mailer class named UserMailer under the app/mailers directory. In the same directory, it will also generate a default ApplicationMailer class. This class may be modified to establish default values for all emails sent from this mailer.
Example:
Editing the Mailer
After we have created the mailer, we must describe its actions. These actions will be used for creating and delivering email messages. In our UserMailer class, for example, we can add a welcome_email method:
- In the above example, we create a function welcome_email that accepts a user object as argument
- Inside the function, the @user instance variable is assigned to the user object
- The mail method is used to create an email message
- In the to parameter, the user's email address is passed
- In the subject parameter, a welcome message as the subject of the email is passed
Creating a Mailer View
Following the definition of the rails mailer action, we must create a view for it. This view is an HTML template that defines the email message's content. To construct the welcome_email view for our UserMailer, create a file welcome_email.html.erb in the app/views/user_mailer directory.
In the above example, we have created an HTML template that shows welcome message to the user.
Calling the Mailer
Now that we've created our rails mailer action and view, we need to call it from our application code. Assume we want to send a welcome email to a user who signs up for our app. To our UsersController#create action, we may add the following code:
In this example, we call the welcome_email method on our UserMailer class, passing the newly created user object as an argument. We then call the deliver_now method to send the email message immediately. Finally, we redirect the user to their profile page.
Header Values Auto Encoding
One of the important characteristics of ActionMailer is the ability to handle multibyte characters in email headers and bodies.
When sending emails, it's important to ensure that the content is encoded properly, especially when dealing with multibyte characters, which can cause issues with email clients. ActionMailer takes care of this by automatically encoding header values, such as the subject line, to ensure they meet email standards and are valid for email clients to display.
ActionMailer Methods
There are mainly three important methods that are required by ActionMailer.
- headers: This method is used to provide the email's header. We can use headers[:field_name] = 'value' or a hash of header field names and value pairs.
- mail: This method creates and sends emails. It receives a hash of parameters as input, which includes the email's topic, recipient, sender, and text.
- attachments: This method is used to attach files to emails. It accepts a hash of parameters as input, which contains the filename and content of the attachment.
Mailer Views
Rails Mailer views are used to generate email templates that are sent by the application. These views are located in the app/views/name_of_mailer_class/ directory, and their name is the same as the mailer method app/views/name_of_mailer_class/mailer_method.html.erb.
We can use the template_path and template_name arguments in the mail method to modify the action's default mailer view.
Mailer Views provide versatility that we may render particular templates or text using a block that is sent to the mail function.
Similar to application views, mailer views also supports fragment caching (also in multipart emails). To enable caching, we need to set the following application configuration:
Action Mailer Layouts
Rails ActionMailer allows developers to use layouts to determine the general structure and style of the email in addition to using views to construct the content of the email.
A layout is a template that is wrapped around the email text. It usually comprises HTML markup that specifies the email's header, footer, and other common parts.
A file with the same name as the mailer method can be created in the layouts folder to serve as the layout for the mailer. For instance, we may build a layout called welcome_email.html.erb in the app/views/layouts folder:
The mailer class UserMailer has a function called welcome_email:
Previewing Emails
Rails ActionMailer allows developers to preview the email before it is sent. This is useful for testing and debugging purposes.
For example:
The above example creates a preview class UserMailerPreview in test/mailers/previews/ directory. It contains a method welcome_email that previews the welcome email generated by the UserMailer class. The preview will be available in http://localhost:3000/rails/mailers/user_mailer/welcome_email
Overall, email previews in Ruby on Rails provide a convenient way for developers to preview and test their email templates before sending them out.
Generating URLs in Action Mailer Views
It is a usual practice to add links to the application's pages in email messages. There are numerous ways to generate URLs for the application's routes using Rails ActionMailer.
Some of the common ones are:
-
url_for:
We use this to create a URL for a route. The controller, action, and any other parameters for the route are included in the hash it accepts as an argument
For Example:
-
Named routes:
It provide a convenient way to generate URLs for specific controller actions. We can use the *_url variant of named route helpers to generate full URLs with the correct domain name.
For Example:
We can also configure the host globally using:
Adding Images in Action Mailer Views
Rails ActionMailer allows developers to include images in the email content to make it more visually appealing.
To add images to the email body, we can use the image_tag helper method. However, since the rails mailer instance doesn't have any context about the incoming request, we need to provide the :asset_host parameter ourselves to specify the URL of our asset host where our application's assets are stored.
We can display the image inside the email by:
This generates an HTML img element with the required src attribute pointing to the asset server's image URL. When the recipient opens the email, the image is downloaded from the asset host and shown in the email body.
Sending Emails Without Template Rendering
We may want to send an email without using a view or a layout at times. Using the text method, Rails ActionMailer allows you to accomplish this.
The custom_email method accepts a user object as an argument, which provides the email ID to which the email is to be sent. The body contains the content of the mail and the content-type is text/html.
Rails Mailer Callbacks
Rails ActionMailer includes numerous callbacks that can be used to customize the mailer's behavior. These callbacks function similarly to ActiveRecord callbacks.
The most commonly used callbacks are:
- before_action, after_action: These callbacks are called before and after the mailer method is executed.
- around_action: This callback allows us to wrap the execution of an email action with custom code. It takes a block that will be executed before and after the email is sent.
Rails ActionMailer Helpers
Since Action Mailer derives from AbstractController, we have access to the majority of the same helpers that Action Controller does. So, when creating email templates, we can use the same helpers that we utilize in our views to display HTML or create URLs.
There are some Action Mailer specific helper methods in ActionMailer::MailHelper in addition to the normal helpers. These, for instance, allow us to access the message as a message and the mailer instance from our view. For example:
ActionMailer Configuration
ActionMailer has various configuration options available that can be used to customize its behavior as required. Some of the most commonly used configuration options are:
-
delivery_method:
This option specifies the method used to deliver the email. The default method is SMTP, but other options include Sendmail, File, and Test.
-
logger:
If information about the mailing run is available, this method generates it. When set to nil, no logging will occur.
-
perform_deliveries:
This setting determines whether email deliveries are to be made. For testing and development, this option is helpful.
Intercepting and Observing Mails
Emails can be altered using interceptors before being sent. An interceptor can be used to add customized headers to emails or to change the email recipient to a test address while they are being developed. To use an interceptor, we need to define an interceptor class that implements the ::delivering_email(message) method. Here’s an example:
Before we can use the interceptor, we must first register it with the interceptors config option in an initializer file such as config/initializers/mail_interceptors.rb:
On the other hand, observers allow us to view the email after it has been sent. For tracking or auditing purposes, this is helpful. We must create an observer class that implements the :delivered_email(message) function in order to utilize an observer. Here's an example:
To register the observer, you need to add it to the observer's config option in an initializer file like config/initializers/mail_observers.rb:
By using interceptors and observers, we can customize the email delivery process in our application and add additional functionality to our email workflow.
Conclusion
- Ruby on Rails ActionMailer is a framework for sending emails from the application.
- It offers a quick and versatile way to create, preview, and send emails utilizing several different delivery options.
- We must first create a mailer, which specifies the email content and delivery choices, before using ActionMailer.
- The email content may be created using mailer views and layouts, and ActionMailer offers tools for creating URLs and including pictures in these views.
- Callbacks and helper modules can also be used to modify the behavior of the mailer and provide custom functionalities.
- For configuring delivery preferences, default URL choices, and other parameters, ActionMailer offers several configuration options.
- We can alter or watch the rails mailer's behavior before or after using interceptors and observers.
- By using Ruby on Rails ActionMailer, we can easily integrate email functionality into our application and create a seamless experience for the users.