Topics Covered in This Ruby on Rails Tutorial:
Installing & Configuring MailCatcher, Creating a Mailer, Sending the Email
Exercise Overview
In this exercise, we'll implement a customer confirmation email system that triggers after checkout completion. Email testing has traditionally presented significant challenges for developers. Setting up production mail servers or configuring reliable SMTP relays requires extensive infrastructure knowledge and careful security considerations. Even with proper setup, development teams often find themselves limited to personal test addresses, battling spam filters, and risking IP blacklisting from misconfigured servers.
The MailCatcher gem elegantly solves these development pain points by creating a local email testing environment. It operates as a lightweight SMTP server on your development machine, intercepting all outgoing emails from configured applications and presenting them through an intuitive web interface. This approach eliminates external dependencies while providing complete visibility into email content, formatting, and delivery metadata. Since MailCatcher runs as a standalone service, it maintains clean separation from your Rails application without cluttering your Gemfile with development-only dependencies.
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.
MailCatcher SolutionMailCatcher runs a dummy mail server on your computer, catching all outgoing email from configured applications and serving them through a web interface for easy testing.
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
cdand 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 nuttyto delete your copy of the nutty site. - Run
git clone https://bitbucket.org/Noble Desktop/nutty.gitto copy the That Nutty Guy Git repository. - Type
cd nuttyto enter the new directory. - Type
git checkout 12Ato bring the site up to the end of the previous exercise. - Run
bundleto install any necessary gems. - Run
yarn install --check-filesto install JavaScript dependencies.
Setting Up the Project Environment
Navigate to Class Files
Open Finder and locate the yourname-Rails Class folder, then open Terminal
Clone Repository
Remove existing nutty folder and clone fresh from Git repository
Install Dependencies
Run bundle and yarn install to set up all necessary gems and JavaScript dependencies
Installing & Configuring MailCatcher
Now that we understand the benefits of local email testing, let's set up MailCatcher and configure Rails to route emails through our development environment.
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.
Independent InstallationMailCatcher runs separately from your Rails app, so you don't need to add it to your Gemfile. This keeps your application dependencies clean.
Restarting the Rails Server
- In Terminal,
cdinto the nutty folder:
- Type
cdand 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,
cdinto the nutty folder:
- Type
cdand 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.
Install MailCatcher as a system-level gem by typing:
gem install mailcatcher
NOTE: Since MailCatcher operates independently of your Rails application, we install it globally rather than adding it to your Gemfile. This approach prevents development tools from polluting your application dependencies while ensuring MailCatcher remains available across all your Rails projects. The installation may take a few moments to complete.
Once installation completes, launch the MailCatcher service:
mailcatcherMailCatcher will display two important addresses upon startup. Note the web interface URL:
http://127.0.0.1:1080
This web interface provides access to all intercepted emails, while the SMTP server listens on port 1025 for outgoing mail from your applications.
Open a browser and navigate to either: http://127.0.0.1:1080 or localhost:1080
Explore MailCatcher's email management interface. Notice the clean, webmail-style layout that will display all intercepted emails with full headers, content preview, and source viewing capabilities. Now we need to configure Rails to route development emails through MailCatcher rather than attempting external SMTP delivery.
Keep MailCatcher open in your browser—we'll return to verify our email delivery shortly.
In your code editor, open nutty > config > environments > development.rb
NOTE: Rails provides three distinct runtime environments by default: development, test, and production. Each environment maintains completely separate configuration settings, allowing you to customize behavior for different deployment scenarios. During local development with rails server, we operate in development mode. This environment-specific approach lets us use MailCatcher locally while configuring real SMTP servers for production deployment. The test environment employs its own email testing strategy, storing messages in memory for automated verification.
In development.rb, locate the existing mailer configuration (around line 35) and add the highlighted code:
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.delivery_method = :smtp
NOTE: This configuration directive instructs Rails to use SMTP (Simple Mail Transfer Protocol) for email delivery instead of the default sendmail approach. SMTP provides more reliable and configurable email transmission, especially when working with external mail services or local testing tools like MailCatcher.
Immediately below that line (around line 36), add the SMTP server configuration:
# 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: These settings point Rails to MailCatcher's SMTP listener. When MailCatcher started, it displayed smtp://127.0.0.1:1025, indicating the SMTP server endpoint. While production SMTP typically uses port 25 (similar to how web servers use port 80), MailCatcher uses port 1025 to avoid conflicts with system mail services and eliminate the need for administrative privileges.
Save and close the file. Your Rails application is now configured to route development emails through MailCatcher.
MailCatcher Installation Process
Install MailCatcher Gem
Run 'gem install mailcatcher' in Terminal - installation may take a minute
Start MailCatcher Service
Type 'mailcatcher' to start the service at http://127.0.0.1:1080
Configure Rails Environment
Update development.rb to use SMTP delivery method with localhost:1025
Rails Environment Configuration
| Feature | Development | Production |
|---|---|---|
| Mail Server | MailCatcher (localhost:1025) | Real SMTP server |
| Purpose | Local testing | Live email delivery |
| Configuration File | development.rb | production.rb |
Creating a Mailer
With MailCatcher configured, we'll now build a Rails mailer to handle order confirmation emails. Rails mailers follow the same architectural patterns as controllers: they prepare data, set instance variables, and render views to generate email content.
Generate a new mailer using Rails' built-in generator:
rails g mailer order_mailerThis command creates the necessary mailer class file along with a corresponding views directory structure for email templates.
Examine the generated application-level mailer configuration by opening: nutty > app > mailers > application_mailer.rb
This file establishes default settings inherited by all mailers in your application, similar to how ApplicationController provides shared functionality for all controllers.
Customize the default sender address to reflect our business domain:
default from: "orders@thatnuttyguy.com"Using a dedicated email address like
orders@creates a professional appearance and helps recipients identify the email's purpose immediately.Save the file and open the specific order mailer: nutty > app > mailers > order_mailer.rb
Implement the confirmation email method by adding the following code around line 2:
class OrderMailer < ApplicationMailer def confirmation_email(order) @order = order mail(to: @order.email, subject: "Your Order #{@order.id} at ThatNuttyGuy.com") end endNOTE: This mailer method mirrors controller architecture. We define a method name (
confirmation_email) that accepts an order parameter, convert it to an instance variable for view access, and call themailmethod to configure recipients and subject line. Rails automatically looks for corresponding view templates to generate the email body content.Save the file. We'll now add the email template files to complete our mailer setup.
Open Finder and navigate to: Desktop > Class Files > yourname-Rails Level 2 Class > snippets
Select both email template files by clicking confirmation_email.html.erb then Shift–clicking on confirmation_email.text.erb
Copy the selected files with Cmd–C
Navigate to the mailer views directory: Desktop > Class Files > yourname-Rails Level 2 Class > nutty > app > views > order_mailer
Paste the template files with Cmd–V
Open the HTML email template: nutty > app > views > order_mailer > confirmation_email.html.erb
Review the template structure. This file functions like any other Rails view, with access to instance variables from the mailer method and standard ERB templating features. The HTML version provides rich formatting capabilities for modern email clients.
Close the HTML template and open the plain text version: nutty > app > views > order_mailer > confirmation_email.text.erb
Providing both HTML and plain text versions follows email best practices and ensures compatibility across all email clients. Recipients with text-only preferences or accessibility requirements can still receive properly formatted order confirmations, while modern clients can choose the optimal rendering format.
Close the text template file. Our mailer is now ready for integration with the checkout process.
A Rails mailer functions similarly to a controller - it prepares messages, sets up instance variables, and renders views containing the message content.
Building the Order Mailer
Generate Mailer Files
Use 'rails g mailer order_mailer' to create the necessary mailer structure
Configure Default Settings
Set the default from email address in application_mailer.rb
Create Email Views
Add both HTML and plain text versions of the confirmation email template
Sending the Email
The final step involves integrating our order mailer into the checkout workflow to automatically send confirmation emails when customers complete their purchases.
Open the cart controller: nutty > app > controllers > cart_controller.rb
We'll trigger the confirmation email immediately after successful order completion and before redirecting the customer to the success page.
Add the email delivery call to the complete method as shown:
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 returnThis implementation ensures the email sends only after successful order processing but before cart cleanup, providing the mailer with all necessary order data while maintaining proper error handling flow.
Save the file and prepare to test the email functionality.
Restart the Rails server to ensure all mailer configurations load properly. In Terminal, stop the current server with Ctrl–C, then restart with
rails s.Test the email system by completing a purchase. Open a new browser tab and navigate to: localhost:3000
Add a product to your cart by selecting any item and clicking the add button.
Proceed to checkout by clicking the Checkout button in your cart.
Switch to your MailCatcher browser tab to view the intercepted email.
Click on the newly received confirmation email to examine its content.
Excellent! The order confirmation email displays properly with all dynamic content populated from the order data.
Click the Plain Text tab within the email viewer to confirm that both HTML and plain text versions were generated and delivered successfully.
This multi-format approach ensures optimal compatibility across diverse email clients and user preferences.
Now that you've verified the email functionality works correctly in the development environment, you can shut down the Rails server. Switch to Terminal and press Ctrl–C to stop the server.
Always send both HTML and plain text versions of emails. Recipients' mail applications can choose which format to render based on user preferences.
Email Integration Checklist
Place OrderMailer call after order completion in the complete action
Ensures server recognizes the new mailer configuration
Add product to cart, checkout, and verify email appears in MailCatcher
Check that both HTML and plain text versions are delivered correctly