Using Action Mailer to Send Emails from a Rails App
Tags: beginners, tutorial, rails
Published: 2023-03-16 03:31:33

This post contains a beginners guide to using Action Mailer to send emails from a Rails app.

My latest project for Flatiron school is [The Carpool App](https://github.com/Miriamfark/Carpool-App) - one central place for parents to post and find carpools for their kids. A big part of parents arranging carpools includes parents communicating with each other, especially to request for their child to join a carpool, and then for the driver of the carpool to either accept or reject the join request. As parents are not expected to keep their eyes glued to the website to see the updates, it became necessary to have the parents updated by sending them an email. 

As my project is built on Rails, Action Mailer was the simplest, built in choice to use to send emails. As Action Mailer is not part of the curriculum at Flatiron, it meant that I needed to teach this bit of technology to myself. At first I was confused about how to implement Action Mailer, but once I got it figured out, and that first email came through, I recognized a familiar "railsy" approach that emphasizes naming conventions and a configuration similar to the MVC pattern (model, view, controller). 

Let's get started! 

1. Generate a mailer

`rails g mailer MailerName`

Generating a mailer is the simplest way to get started as Rails will generate the following files: 

- app/mailers/mailer_name_mailer.rb

- app/views/mailer_name_mailer

- test files in both spec/mailers/mailer_name_spec.rb and 

- spec/mailers/previews/mailer_name_preview.rb

2. Decide the default email address

All of the mailers inherit from ApplicationMailer. If all of the emails in your app will be coming from the same email address, you can set the default email in one location, in the ApplicationMailer.

```
class ApplicationMailer < ActionMailer::Base
  default from: 'example@gmail.com'
  layout 'mailer'
end
```
You will probably want to open up a new email account with your app name in it to send out app related emails. 

3. Add an Email Action to the Mailer

The next step is actually deciding what email you would like to send. For example, if you would like to send an email welcoming a new user to the app, you can create a welcome email. This would simply be a method in you mailer, defining the name of the email, what parameters are being passed in, where the email should be sent, and the subject of the email.

```
def welcome_email(user)
    @user = user
    mail(to: @user.email, subject: 'Welcome to The Carpool App')
  end
```

4. Creating a View

After defining the email, it is time to decide what the email should look like. What will the email say? This is determined in by creating a new file in app/views/mailer_name_mailer called `welcome_email.html.erb`. It is important to note two things. Firstly, the name of the file must be in the folder named after your mailer. Secondly, the file must follow the naming conventions of being called the same name as your email method. This sticks to a Rails principle of convention over configuration, meaning that by following conventions there is a lot less work required to configure the different files.

Note: This file is an html.erb file, which is an html file with ruby embedded within. 

Once you have created the file, copy and paste the following inside.

```
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Welcome to The Carpool App!</h1>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html>
```
You can edit or add any other information inside the email. Using interpolation you could personalize the email with the user's name.

`<h1>Welcome to The Carpool App, <%= @user.name %>!</h1>`

... or add a link to bring the user back to your app ...

`    <a href="<%= @url %>" target="_blank">Click Here!</a>
`

5. Call the Email Method in a Controller

Now that you have figured out exactly what the email should look like and what it should say, you need to call the email method. The best place to do this is in a controller action. As my example is an email sent when a new user signs up for an account, I will call the email method in my create action of the Users Controller.

```
class UsersController < ApplicationController
    skip_before_action :authorize, only: [:create]

    def create
        user = User.create!(user_params)
        session[:user_id] = user.id
        if user
            MailerNameMailer.welcome_email(user).deliver_now
        end
        render json: user, status: :created
    rescue ActiveRecord::RecordInvalid => e
        render json: { errors: e.record.errors.full_messages }, status: :unprocessable_entity
    end

end
```

6. Config

To ensure that everything will work correctly, copy and paste the following into your config/environments/development.rb file.

```
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.perform_deliveries = true
```

If you choose to have your emails sent from a gmail account, you will need to include the following.

```
config.action_mailer.default_options = {from: 'example@gmail.com'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address:              'smtp.gmail.com',
port:                 587,
user_name:            'example',
password:             'password',
authentication:       'plain',
enable_starttls_auto: true  }
```
I had some trouble with gmail allowing me to sign in from my app, and so I had to go into my new gmail account, enable [two step verfication](https://support.google.com/accounts/answer/185839), and then create an [app specific password](https://support.google.com/mail/answer/185833?hl=en-GB) to include above.

Another great option is to use the [letter opener gem](https://rubygems.org/gems/letter_opener/versions/1.4.1). This is a great tool to use in development, because instead of the app actually sending the email, instead it opens a new tab on your browser with the email view. This is really helpful to see what is going on with the email as it happens. If you are using the letter opener gem, you would need to install it:

`gem install letter_opener -v 1.4.1`

and include it in your config/environments/development.rb file.

`  config.action_mailer.delivery_method = :letter_opener
` 
    
And that is it! You are now ready to send an email from your Rails app!