Action Mailers in Rails 4

email.jpeg

I wrote and re-wrote the code to get this very simple thing working so, I decided to dedicate a blog post to the walkthrough that I wish I could have found when I googled.

Here is how-to on setting up a mailer in Rails 4:

But first, check out the rails guide on mailers. It is thorough and helpful. But for some reason I couldn’t quite get mine working by only referencing the rails guide. So here are the steps that I took to (finally!) get my mailer working.

1. Generate your Mailer
Mailers are like controllers, sort of. Like a controller has a model and view, so does the mailer. A controller renders a view (using HTML), and a mailer renders a view using (SMTP). So instead of a web page, you get an email. In order to generate a mailer, you use a generator like how you would for a controller.

rails generate mailer MailerName

If you want to create a mailer with certain actions when you generate, then list this after, similar to how you would with adding actions to a controller

ex:
rails generate mailer MailerName welcome contact_us

2. Check out the Mailer
Now there should be a in the app/mailer folder of your rails app.
When you open it, there should be a default from statement similar to:

default from: 'info@example.com' 

then you will see actions that you generated. If you need to set up an action, you do it here with a format similar to this

def welcome(user)
    @user = user
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site'
  end

This is passing the variable user, and setting an instance variable as well. What this means is that you can now use this instance variable in your view, which will become an email. There are many other things that you can do here. Check out the guide to see more options.

3. Create a View
There will be a folder for your mailer in the views folder, but you may need to create a new file for your view.

using the example above your file would be named:

welcome.html.erb

and it is good practice to have a text version as well

welcome.text.erb

now you can add stuff like this (HTML)

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' /><br>
  </head>
  <body>
    <h1>Welcome to example.com, <%= @user.name %></h1>
    <p>
      You have successfully signed up to example.com,
      your username is: <%= @user.login %>.
    </p>
    <p>
      To login to the site, just follow this link: <%= @url %>.
    </p>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html> 

and this (text)

Welcome to example.com, <%= @user.name %>
===============================================

You have successfully signed up to example.com,
your username is: <%= @user.login %>.

To login to the site, just follow this link: <%= @url %>.

Thanks for joining and have a great day!

4. Update your Controller
If you are just beginning your app, you can generate a quick User scaffold and that will give you a controller to tie your mailer to.

rails generate scaffold user name email login

If you already have your model and controller set up, make sure to update the controller, usually for the create action:

class UsersController < ApplicationController
...
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        # Tell the UserMailer to send a welcome email after save
        UserMailer.welcome(@user).deliver

        format.html { redirect_to(@user, notice: 'User was successfully created.') }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
end

5. Set Up your Config (correctly)
This is where I went wrong, so complete this with caution.
You need to go to config/environment/development

uncomment this line, set it to true if you want to see errors if your mailer doesn’t work correctly.

config.action_mailer.raise_delivery_errors = false

Then add the this underneath. This is the SMTP for google.

 **config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                 587,
    domain:               'gmail.com',
    user_name:            'email_account_I_will_send_from@gmail.com',
    password:             'password to my account',
    authentication:       'plain',
    enable_starttls_auto: true  }

Now if you test, it should be working just perfect. Remember to repeat this in config/environments/production for when you push this live. I…unfortunately forgot that step and caused myself some heartache trying to figure out where I went wrong. Here’s hoping that this helps you avoid that mistake.

 
21
Kudos
 
21
Kudos

Now read this

What Matters

This week of thanksgiving has been for me a much needed break and a chance to spend long overdue time with family. It has also given me the chance to think. The past few years have been like a whirlwind for me, and in many ways I am... Continue →