Back to list
bastos

action-mailer

by bastos

Bastos' Claude Code Ruby Plugin Marketplace

0🍴 0📅 Jan 24, 2026

SKILL.md


name: action-mailer description: This skill should be used when the user asks about "email", "mailers", "Action Mailer", "deliver_now", "deliver_later", "email templates", "attachments", "mail previews", "SMTP", "email configuration", "interceptors", or needs guidance on sending emails in Rails applications. version: 1.0.0

Action Mailer

Comprehensive guide to sending emails in Rails applications.

Creating Mailers

rails generate mailer User welcome reset_password
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: "noreply@example.com"
  layout "mailer"
end

# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  def welcome(user)
    @user = user
    @login_url = login_url

    mail(
      to: @user.email,
      subject: "Welcome to Our App!"
    )
  end

  def reset_password(user)
    @user = user
    @reset_url = edit_password_url(token: @user.reset_token)

    mail(to: @user.email, subject: "Reset Your Password")
  end
end

Mail Options

mail(
  to: "user@example.com",           # Single recipient
  to: ["a@ex.com", "b@ex.com"],     # Multiple recipients
  from: "sender@example.com",
  cc: "manager@example.com",
  bcc: "archive@example.com",
  reply_to: "support@example.com",
  subject: "Email Subject",
  content_type: "text/html",        # Default is multipart
  importance: "high",
  delivery_method_options: { ... }
)

Default Values

class ApplicationMailer < ActionMailer::Base
  default from: "noreply@example.com",
          reply_to: "support@example.com"
end

class UserMailer < ApplicationMailer
  default from: "users@example.com"  # Override for this mailer
end

Using Params

# Passing params
UserMailer.with(user: @user, account: @account).welcome.deliver_later

# Accessing params
class UserMailer < ApplicationMailer
  def welcome
    @user = params[:user]
    @account = params[:account]
    mail(to: @user.email)
  end
end

Email Templates

Directory Structure

app/views/user_mailer/
├── welcome.html.erb      # HTML version
├── welcome.text.erb      # Plain text version
└── reset_password.html.erb

HTML Template

<%# app/views/user_mailer/welcome.html.erb %>
<h1>Welcome, <%= @user.name %>!</h1>

<p>Thanks for signing up. Get started by visiting your dashboard:</p>

<p><%= link_to "Go to Dashboard", dashboard_url %></p>

<p>
  Best regards,<br>
  The Team
</p>

Plain Text Template

<%# app/views/user_mailer/welcome.text.erb %>
Welcome, <%= @user.name %>!

Thanks for signing up. Get started by visiting your dashboard:
<%= dashboard_url %>

Best regards,
The Team

Layouts

<%# app/views/layouts/mailer.html.erb %>
<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <style>
      body { font-family: Arial, sans-serif; }
      .header { background: #3498db; color: white; padding: 20px; }
      .content { padding: 20px; }
      .footer { color: #666; font-size: 12px; padding: 20px; }
    </style>
  </head>
  <body>
    <div class="header">
      <%= image_tag attachments['logo.png'].url if attachments['logo.png'] %>
    </div>
    <div class="content">
      <%= yield %>
    </div>
    <div class="footer">
      <p>&copy; <%= Date.current.year %> Our Company</p>
      <p><%= link_to "Unsubscribe", unsubscribe_url %></p>
    </div>
  </body>
</html>

Attachments

File Attachments

class ReportMailer < ApplicationMailer
  def monthly_report(user, report)
    @user = user

    # From file
    attachments["report.pdf"] = File.read(report.path)

    # With options
    attachments["data.csv"] = {
      mime_type: "text/csv",
      content: generate_csv(report)
    }

    mail(to: @user.email, subject: "Monthly Report")
  end
end

Inline Attachments

def welcome(user)
  @user = user
  attachments.inline["logo.png"] = File.read("app/assets/images/logo.png")
  mail(to: @user.email)
end
<%# In template %>
<%= image_tag attachments['logo.png'].url %>

Sending Emails

# Queue for background delivery
UserMailer.welcome(@user).deliver_later

# With delay
UserMailer.welcome(@user).deliver_later(wait: 1.hour)
UserMailer.welcome(@user).deliver_later(wait_until: Date.tomorrow.noon)

# With options
UserMailer.welcome(@user).deliver_later(queue: :mailers, priority: 10)

Synchronous

# Send immediately (blocks)
UserMailer.welcome(@user).deliver_now

# Useful in background jobs
class WelcomeJob < ApplicationJob
  def perform(user)
    UserMailer.welcome(user).deliver_now
  end
end

Email Previews

# test/mailers/previews/user_mailer_preview.rb
class UserMailerPreview < ActionMailer::Preview
  def welcome
    user = User.first || User.new(name: "Test User", email: "test@example.com")
    UserMailer.welcome(user)
  end

  def reset_password
    user = User.first
    UserMailer.reset_password(user)
  end
end

Access at: http://localhost:3000/rails/mailers/user_mailer/welcome

Configuration

Development

# config/environments/development.rb
config.action_mailer.delivery_method = :letter_opener  # View in browser
# or
config.action_mailer.delivery_method = :test  # Store in ActionMailer::Base.deliveries

config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_caching = false

Production (SMTP)

# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { host: "example.com" }

config.action_mailer.smtp_settings = {
  address: "smtp.example.com",
  port: 587,
  domain: "example.com",
  user_name: Rails.application.credentials.smtp[:user],
  password: Rails.application.credentials.smtp[:password],
  authentication: "plain",
  enable_starttls_auto: true
}

Common Providers

# SendGrid
config.action_mailer.smtp_settings = {
  address: "smtp.sendgrid.net",
  port: 587,
  authentication: :plain,
  user_name: "apikey",
  password: ENV["SENDGRID_API_KEY"],
  domain: "example.com",
  enable_starttls_auto: true
}

# Mailgun
config.action_mailer.smtp_settings = {
  address: "smtp.mailgun.org",
  port: 587,
  user_name: ENV["MAILGUN_SMTP_LOGIN"],
  password: ENV["MAILGUN_SMTP_PASSWORD"],
  authentication: :plain,
  enable_starttls_auto: true
}

Interceptors and Observers

Interceptor (Modify Before Sending)

# app/mailers/sandbox_email_interceptor.rb
class SandboxEmailInterceptor
  def self.delivering_email(message)
    message.to = ["sandbox@example.com"]
    message.subject = "[SANDBOX] #{message.subject}"
  end
end

# config/initializers/mail_interceptors.rb
if Rails.env.staging?
  ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
end

Observer (Log After Sending)

# app/mailers/email_delivery_observer.rb
class EmailDeliveryObserver
  def self.delivered_email(message)
    EmailLog.create!(
      to: message.to.join(", "),
      subject: message.subject,
      sent_at: Time.current
    )
  end
end

# config/initializers/mail_observers.rb
ActionMailer::Base.register_observer(EmailDeliveryObserver)

Testing

Minitest

require "test_helper"

class UserMailerTest < ActionMailer::TestCase
  test "welcome email" do
    user = users(:one)
    email = UserMailer.welcome(user)

    assert_emails 1 do
      email.deliver_now
    end

    assert_equal ["noreply@example.com"], email.from
    assert_equal [user.email], email.to
    assert_equal "Welcome to Our App!", email.subject
    assert_match user.name, email.body.encoded
  end

  test "welcome email is enqueued" do
    user = users(:one)

    assert_enqueued_emails 1 do
      UserMailer.welcome(user).deliver_later
    end
  end
end

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon