Skip to main content
March 23, 2026Noble Desktop Publishing Team/9 min read

Confirmation Emails & Testing with MailCatcher

Master Email Testing in Rails Development

Common Email Testing Challenges

Server Configuration

Setting up mail servers or finding reliable relays is complex and time-consuming. Improper configuration can lead to blacklisting.

Delivery Issues

Test emails frequently end up in spam folders or get filtered out by email providers before reaching their destination.

Limited Testing Options

Developers are typically restricted to sending emails to their own addresses or designated test accounts only.

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.

  1. 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 Solution

    MailCatcher 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)

  1. Close any files you may have open.
  2. Open the Finder and navigate to Class Files > yourname-Rails Class
  3. Open Terminal.
  4. Type cd and a single space (do NOT press Return yet).
  5. Drag the yourname-Rails Class folder from the Finder to the Terminal window and press ENTER.
  6. Run rm -rf nutty to delete your copy of the nutty site.
  7. Run git clone https://bitbucket.org/Noble Desktop/nutty.git to copy the That Nutty Guy Git repository.
  8. Type cd nutty to enter the new directory.
  9. Type git checkout 12A to bring the site up to the end of the previous exercise.
  10. Run bundle to install any necessary gems.
  11. Run yarn install --check-files to install JavaScript dependencies.

Setting Up the Project Environment

1

Navigate to Class Files

Open Finder and locate the yourname-Rails Class folder, then open Terminal

2

Clone Repository

Remove existing nutty folder and clone fresh from Git repository

3

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.

  1. 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).

  2. 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 Installation

    MailCatcher 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

  1. 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.
  1. In Terminal, type the following:

    rails s
  2. Open a new tab (Cmd–T) leaving our server running in the old tab.
  3. 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.
  • 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:

    mailcatcher
  • MailCatcher 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

    1

    Install MailCatcher Gem

    Run 'gem install mailcatcher' in Terminal - installation may take a minute

    2

    Start MailCatcher Service

    Type 'mailcatcher' to start the service at http://127.0.0.1:1080

    3

    Configure Rails Environment

    Update development.rb to use SMTP delivery method with localhost:1025

    Rails Environment Configuration

    FeatureDevelopmentProduction
    Mail ServerMailCatcher (localhost:1025)Real SMTP server
    PurposeLocal testingLive email delivery
    Configuration Filedevelopment.rbproduction.rb
    Recommended: Development environment uses MailCatcher for safe testing without affecting real email addresses

    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.

    1. Generate a new mailer using Rails' built-in generator:

      rails g mailer order_mailer

      This command creates the necessary mailer class file along with a corresponding views directory structure for email templates.

    2. 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.

    3. 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.

    4. Save the file and open the specific order mailer: nutty > app > mailers > order_mailer.rb

    5. 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
      end

      NOTE: 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 the mail method to configure recipients and subject line. Rails automatically looks for corresponding view templates to generate the email body content.

    6. Save the file. We'll now add the email template files to complete our mailer setup.

    7. Open Finder and navigate to: Desktop > Class Files > yourname-Rails Level 2 Class > snippets

    8. Select both email template files by clicking confirmation_email.html.erb then Shift–clicking on confirmation_email.text.erb

    9. Copy the selected files with Cmd–C

    10. Navigate to the mailer views directory: Desktop > Class Files > yourname-Rails Level 2 Class > nutty > app > views > order_mailer

    11. Paste the template files with Cmd–V

    12. Open the HTML email template: nutty > app > views > order_mailer > confirmation_email.html.erb

    13. 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.

    14. 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.

    15. Close the text template file. Our mailer is now ready for integration with the checkout process.

    Mailer Architecture

    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

    1

    Generate Mailer Files

    Use 'rails g mailer order_mailer' to create the necessary mailer structure

    2

    Configure Default Settings

    Set the default from email address in application_mailer.rb

    3

    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.

    1. 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.

    2. 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 return

      This 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.

    3. Save the file and prepare to test the email functionality.

    4. 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.

    5. Test the email system by completing a purchase. Open a new browser tab and navigate to: localhost:3000

    6. Add a product to your cart by selecting any item and clicking the add button.

    7. Proceed to checkout by clicking the Checkout button in your cart.

    8. Switch to your MailCatcher browser tab to view the intercepted email.

    9. 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.

    10. 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.

    11. 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.

    Dual Format Best Practice

    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

    0/4

    Key Takeaways

    1MailCatcher solves common email testing challenges by providing a local dummy mail server that catches outgoing emails and displays them in a web interface
    2Traditional email testing involves complex server setup, delivery issues with spam filters, and limited testing address options
    3MailCatcher runs independently from Rails applications and doesn't require Gemfile inclusion, keeping application dependencies clean
    4Rails mailers function similarly to controllers, preparing messages with instance variables and rendering views for email content
    5Different Rails environments (development, test, production) can have completely different email configurations for various deployment scenarios
    6Best practice requires sending both HTML and plain text versions of emails to accommodate different user preferences and email client capabilities
    7SMTP configuration in development.rb uses localhost:1025 to route emails through MailCatcher instead of real mail servers
    8Email integration should be placed after order completion in the controller flow to ensure confirmation emails are sent at the appropriate time

    RELATED ARTICLES