Supermail 0.2.x
has been released! It’s a better way to work with emails in Rails.
Here’s what a Supermail email looks like:
# $ rails generate supermail:email User::Welcome
# ./app/emails/user/welcome.rb
class User::WelcomeEmail < ApplicationEmail
def initialize(person:)
@person = person
end
def to = @person.email
def subject = "Welcome to Beautiful Ruby"
def body
super do
<<~_
Hi #{@person.name},
You're going to learn a ton at https://beautifulruby.com.
_
end
end
end
When you want to use it to send an email, you just initialize the thing like you would any Ruby class and send it.
# You might call this from a controller
User::WelcomeEmail.new(person: @person).deliver_now
ActionMailer is frustrating
Action Mailer is one of the most frustrating parts of Rails. The problem I have with it is I can never remember how to initialize it and send an email.
# Is it this?
UserMailer.welcome(@user).deliver_now
# Or is it this?
UserMailer.with(user: @user).welcome.deliver_now
# Mabye this?
UserMailer.new.welcome(@user).deliver_now
# Or is it something else? 🤷
There are too many levels of indirection for no apparent reason and it doesn’t really make sense to group a bunch of emails into one class.
class UserMailer < ApplicationMailer
# Why a `default1 class method with a hash? Methods are cool!
default from: "notifications@example.com"
def welcome_email
# This is weird, where do params come from? Can I access these from the template?
@user = params[:user]
# Ok this is reasonable.
@url = "http://example.com/login"
# Is this mailing the thing or just generating a message? Where is the body?
mail(to: @user.email, subject: "Welcome to My Awesome Site")
end
end
All of that can be modeled more simply in a plain ‘ol Ruby object. In fact, here’s the source code for Supermail’s base email class:
class Base
delegate :deliver, :deliver_now, :deliver_later, to: :message_delivery
def to = nil
def from = nil
def subject = nil
def body = ""
def message
message_delivery.message
end
def message_delivery
ActionMailer::Base.mail(to:, from:, subject:, body:)
end
end
Watch the video
I shot a late night Read the Friendly Source Code video that covers ActionMailer and Supermail.
Start using Supermail
If you want to start using Supermail, you can install it by adding it to your Gemfile:
bundle add supermail
Then run the install generator:
rails generate supermail:install
You’ll see a new file at app/emails/application_email.rb
that can be customized as your base email class.
It’s already hooked up to your Rails ActionMailer configuration, so there’s no additional configuration required.