Back to Blog
Tutorial11/19/2025

Mailstify #5 - Email Logic and Previews (Action Mailer)

Mailstify #5 - Email Logic and Previews (Action Mailer)

This chapter connects your rich-text Campaign content to Rails' email delivery system. We'll create a dedicated mailer class to handle sending, implement personalization, and configure the necessary preview environment.

Mailstify Table of Contents


1. Generate the Action Mailer Class

Every email type needs its own mailer class. We'll generate one specifically for sending campaigns:

bin/rails generate mailer campaign

This command creates:

  • app/mailers/campaign_mailer.rb
  • app/mailers/application_mailer.rb (if not already present)
  • Directories for email templates (app/views/campaign_mailer/)

2. Design the Mailer Action

Open app/mailers/campaign_mailer.rb and define the action responsible for sending the email. This action will accept the Campaign object and a Subscriber object for personalization:

class CampaignMailer < ApplicationMailer
  # The method name (e.g., campaign_email) must match the template name
  def campaign_email(campaign, subscriber)
    # Store objects for access in the view templates
    @campaign = campaign
    @subscriber = subscriber

    # Use the Campaign's subject line
    mail(
      to: @subscriber.email,
      subject: @campaign.subject,
      from: "Mailstify <noreply@mailstify.com>" # Use your desired sender address
    )
  end
end

3. Design the Email Templates

Action Mailer uses standard ERB templates, defaulting to multi-part emails (HTML and plain text). The template files must match the action name (campaign_email).

A. HTML Template (campaign_email.html.erb)

This template will render the rich content from Action Text. The raw helper is crucial here because the ActionText::RichTextobject renders safe HTML which should not be re-escaped by ERB.

Create app/views/campaign_mailer/campaign_email.html.erb:

<!DOCTYPE html>
<html>
<head>
  <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  <style>
    /* Basic email client compatibility styles */
    body { font-family: Arial, sans-serif; }
    .content-container { max-width: 600px; margin: 0 auto; padding: 20px; }
  </style>
</head>
<body>
  <div class="content-container">
    <p>Hi <%= @subscriber.name || 'there' %>,</p>

    <%= raw @campaign.body %>

    <hr style="margin-top: 30px; border: 0; border-top: 1px solid #eee;">
    <p style="font-size: 12px; color: #999;">
      You received this email because you subscribed to <%= @campaign.list.name %>.
    </p>
  </div>
</body>
</html>

B. Plain Text Template (campaign_email.text.erb)

Plain text templates are essential for accessibility and for email clients that block HTML.

Create app/views/campaign_mailer/campaign_email.text.erb:

Hi <%= @subscriber.name || 'there' %>,

<%= @campaign.body.to_plain_text %>

---

You received this email because you subscribed to <%= @campaign.list.name %>.

4. Implement Basic Email Personalization

Personalization is implemented by accessing the @subscriber instance variable (set in the mailer) directly in the templates.

  • In both templates, we used: <%= @subscriber.name || 'there' %>
  • In the text template, we used: <%= @campaign.body.to_plain_text %> (Action Text provides a simple method to strip HTML).

5. Configure and Use Mailer Previews

Mailer Previews allow you to check the rendering of your email templates in the browser without sending any actual mail. This is vital for debugging layout issues.

A. Configure the Preview Host

Since your templates use full URLs (for images), you must set the host for the preview environment.

Update config/environments/development.rb with:

# config/environments/development.rb

Rails.application.configure do
  # ... other settings ...

  # Ensure these lines are present to generate correct links in emails/previews
  config.action_controller.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end

B. Create the Mailer Preview Class

The Mailer Preview class is located in the root /test directory.

Create the file at test/mailers/previews/campaign_mailer_preview.rb:

# test/mailers/previews/campaign_mailer_preview.rb

# Preview all emails at <http://localhost:3000/rails/mailers/campaign_mailer>
class CampaignMailerPreview < ActionMailer::Preview
  def campaign_email
    # 1. Find the latest Campaign with content (you should have one from Part 4)
    campaign = Campaign.last

    # 2. Find a sample Subscriber (or create a dummy one)
    # Assuming you have a List model and a Subscriber model
    list = campaign.list || List.first

    # Create a dummy subscriber if none exists for a reliable preview
    subscriber = Subscriber.new(
      email: "jane.doe@example.com",
      name: "Jane",
      list: list
    )

    # 3. Pass both objects to the mailer action
    CampaignMailer.campaign_email(campaign, subscriber)
  end
end

6. Test the Mailer Preview

  1. Start your Rails server (if it's not running):

    rails s
    
  2. Navigate to the Mailer Previews URL in your browser: http://localhost:3000/rails/mailers

  3. Click on the CampaignMailer link, and then the campaign_email link to view your HTML and Text previews side-by-side. Ensure the rich content renders correctly, including images, and that the personalization (Hi Jane) works.

Pasted image 20251110173056.png
Pasted image 20251110173056.png


Conclusion of Part 5: Ready for Dispatch

In this chapter, we successfully integrated our rich campaign content into the Rails email system. We established the CampaignMailer, designed multi-part (HTML and text) templates, and implemented essential personalization using subscriber data. Most critically, we set up the Mailer Preview environment, allowing you to debug and finalize your email design directly in the browser.

The campaign is now fully designed and ready to be sent. In Part 6, we will use Solid Queue to handle the asynchronous bulk dispatch of this email to all subscribers, moving Mailstify closer to a fully functional email service.

Comments

Loading comments...

Level Up Your Dev Skills & Income 💰💻

Learn how to sharpen your programming skills, monetize your expertise, and build a future-proof career — through freelancing, SaaS, digital products, or high-paying jobs.

Join 3,000+ developers learning how to earn more, improve their skills, and future-proof their careers.