Discover the step-by-step process for installing and configuring MailCatcher, creating a mailer, and sending an email within a Ruby on Rails application in our comprehensive tutorial.
This exercise is excerpted from Noble Desktop’s past web development training materials. Noble Desktop now teaches JavaScript and the MERN Stack in our Full Stack Development Certificate. To learn current skills in web development, check out our coding bootcamps in NYC and live online.
Topics covered in this Ruby on Rails tutorial:
Installing & configuring MailCatcher, Creating a mailer, Sending the email
Exercise Overview
In this exercise, we’ll work on sending our customers a confirmation email after checkout. Historically, testing email has been inconvenient for a number of reasons. First of all, setting up a mail server or identifying a relay you can use is not exactly easy. Second, even after you get this setup in place, you’re usually stuck sending emails to your own addresses or test addresses. Test emails often end up in spam folders or get filtered out by your email provider before you can see them. Configuring your own email server improperly can even get you blacklisted.
The MailCatcher gem solves these problems. It runs a dummy mail server on your computer, which catches all outgoing email (from applications you configure to use MailCatcher). It then serves up those emails through a web interface so you can see what was sent and to whom. MailCatcher runs separately from your Rails app so you don’t need to put it in your Gemfile. You do need to install it, however.
-
If you completed the previous exercises, you can skip the following sidebar. We recommend you finish the previous exercises (8A–12A) before starting this one. If you haven’t finished them, do the following sidebar.
If You Did Not Do the Previous Exercises (8A–12A)
- Close any files you may have open.
- Open the Finder and navigate to Class Files > yourname-Rails Class
- Open Terminal.
- Type
cd
and a single space (do NOT press Return yet). - Drag the yourname-Rails Class folder from the Finder to the Terminal window and press ENTER.
- Run
rm -rf nutty
to delete your copy of the nutty site. - Run
git clone https://bitbucket.org/noble-desktop/nutty.git
to copy the That Nutty Guy git repository. - Type
cd nutty
to enter the new directory. - Type
git checkout 12A
to bring the site up to the end of the previous exercise. - Run
bundle
to install any necessary gems. - Run
yarn install --check-files
to install JavaScript dependencies.
Installing & Configuring MailCatcher
-
For this exercise, we’ll continue working with the nutty folder located in Desktop > Class Files > yourname-Rails Class > nutty.
If you haven’t already done so, we suggest opening the nutty folder in your code editor if it allows you to (like Sublime Text does).
-
You should still have a window with two tabs open in Terminal from the last exercise, the first of which is running the server. If you don’t, complete the following sidebar.
Restarting the Rails Server
- In Terminal,
cd
into the nutty folder:
- Type
cd
and a space. - Drag the nutty folder from Desktop > Class Files > yourname-Rails Class onto the Terminal window (so it will type out the path for you).
- In Terminal, hit Return to change directory.
-
In Terminal, type the following:
rails s
- Open a new tab (Cmd–T) leaving our server running in the old tab.
- In the new tab,
cd
into the nutty folder:
- Type
cd
and a space. - Drag the nutty folder from Desktop > Class Files > yourname-Rails Class onto the Terminal window (so it will type out the path for you).
- In Terminal, hit Return to change directory.
- In Terminal,
-
Type the following:
gem install mailcatcher
NOTE: Because this is not part of our Rails app, we won’t need to restart the Rails server. However, it may take a minute to install.
-
After it installs, start up MailCatcher by simply typing:
mailcatcher
-
It returned an address. This shows where you can access MailCatcher in the browser:
http://127.0.0.1:1080
Open a browser and navigate to either: http://127.0.0.1:1080 or localhost:1080
Check out MailCatcher’s web mail-like interface. We need to configure Rails to send email through MailCatcher, not a default SMTP port.
Leave MailCatcher open in the browser so we can return to it later.
-
In your code editor, open nutty > config > environments > development.rb
NOTE: We’ll be looking more closely at environments when we deploy our app later on, but for now, know that Rails has three of them by default: test.rb, development.rb, and production.rb. Each of them can have completely different settings. The environment that we’re in when running the Rails server is usually development. So for development purposes only, we’re setting up MailCatcher. Our production environment will likely contain settings corresponding to a real mail server. The test environment has its own method for testing email where it just sends them to itself then checks them.
-
In development.rb, add the following bold code (around line 35):
# Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false config.action_mailer.delivery_method = :smtp
NOTE: This line tells Rails we want to send mail through SMTP, which is the standard outgoing email protocol. We could add this code anywhere in this file, but it makes sense to put it here to keep things organized.
-
Just below that, around line 36, add:
# Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'localhost', port: '1025' }
NOTE: If you need to know what port to use, look at Terminal and notice that after MailCatcher was started, it listed:
smtp://127.0.0.1:1025
. Normally, SMTP runs on port 25 just like a web server normally runs on port 80, so the mail server is staking out that territory for itself by rounding it up to the 1000s. Save the file, then close it.
Creating a Mailer
A Rails mailer is a lot like a controller: It prepares a message for delivery, sets up instance variables, and even renders one or more views containing the content of the message.
-
Create a mailer by typing the following command in Terminal:
rails g mailer order_mailer
Let’s check out the mailer files that were just created. In your code editor, open the following file: nutty > app > mailers > application_mailer.rb
-
Notice that a default
from
email address was specified. Let’s customize it. Edit the code as shown in bold:default from: "orders@thatnuttyguy.com"
Save the file and open ordermailer file.
-
Next we can start building our first mailer method. Around line 2, add the following bold code:
class OrderMailer < ApplicationMailer def confirmation_email(order) @order = order mail(to: @order.email, subject: "Your Order #{@order.id} at ThatNuttyGuy.com") end end
NOTE: This mailer method looks a lot like a controller method. We need to find the name of the email (
confirmation_email
) and prepare to receive a single parameter (order
), which we convert to an instance variable (@order
) so that our views can access it. Then we send an email to the customer. The actual contents of the email will go in a couple views. -
Save the file.
To save time, we’ve given you a few code snippets that you can copy/paste.
Open a Finder window and navigate to: Desktop > Class Files > yourname-Rails Level 2 Class > snippets.
Click on confirmation_email.html.erb then Shift–click on confirmation_email.text.erb to select both.
Hit Cmd–C to copy them.
Navigate to: Desktop > Class Files > yourname-Rails Level 2 Class > nutty > app > views > order_mailer.
Hit Cmd–V to paste the files in that folder.
In your code editor, open the following file (the HTML version of the email):
nutty > app > views > order_mailer > confirmation_email.html.erbScan over the file. You can see that this is a pretty generic HTML document that looks like almost any other view we’d write.
Close the file.
-
In your code editor, open the following file (the plain text version of the email):
nutty > app > views > order_mailer > confirmation_email.text.erbThis is the plain text version of the email. Remember that when we send emails, it’s always a good practice to send both an HTML version as well as a plain text version. Different people have different preferences for what kind of emails they receive. This way, we send both and the recipient’s mail application can choose which to render.
Close the file.
Sending the Email
Let’s go ahead and try sending an email.
-
In your code editor, open nutty > app > controllers > cart_controller.rb
We want this email to be sent as a confirmation after a customer places their order and it has been finalized.
-
Add the code shown in bold (it can go anywhere after the order is finished):
def complete @order = Order.new(customer: current_customer) @order.line_items = @cart.line_items @order.save @cart.destroy OrderMailer.confirmation_email(@order).deliver redirect_to '/cart/complete' and return
Save the file.
Stop and restart the Rails server to make sure it knows about the new mailer we created.
Let’s test this out by making a purchase. In the browser, open a new tab or window and navigate to: localhost:3000
Choose a product and add it to your cart.
In your cart, click Checkout.
Go to the MailCatcher tab or window in the browser.
-
You should see that you’ve received an email. Click on it.
Awesome, we got an order confirmation!
-
Click the Plain Text tab in the email to see that the Plain Text version was included in addition to HTML! Awesome!
Now that we’re done working in the development environment (writing code and testing our app on our local server), we can shut down the Rails server.
Switch to Terminal and hit Ctrl–C to shut down the server.