← Blog • Published: Sunday, 29 Oct 2023

Rails Generate Mailer (quick breakdown)

This is a short and sweet article covering rails generate mailer, the Rails generator for ActionMailer, plus all it's options. I cover it's basic usage to generate an ActionMailer mailer with some mailer methods, then dig into all the flags we can pass.

Ruby on Rails ships with a bunch of handy generators (run bin/rails generate to see them all) — one of those generators is for ActionMailer mailers.

The Rails mailer generator is a handy way to quicky spin up a new mailer in for your Rails app, and it includes a couple of handy flags you can pass. In this article, I want to give you a quick rundown of how to use rails generate mailer, starting with a quick example, and then digging into all it's options.

As a reference, here's the help info for the Rails mailer generator — to get this, I just ran rails g mailer in my terminal, and Rails output this handy help info (and this works for all rails generate commands!) —

❯ rails g mailer
Usage:
  rails generate mailer NAME [method method] [options]

Options:
      [--skip-namespace], [--no-skip-namespace]              # Skip namespace (affects only isolated engines)
      [--skip-collision-check], [--no-skip-collision-check]  # Skip collision check
  -e, [--template-engine=NAME]                               # Template engine to be invoked
                                                             # Default: tailwindcss
  -t, [--test-framework=NAME]                                # Test framework to be invoked
                                                             # Default: rspec

Runtime options:
  -f, [--force]                    # Overwrite files that already exist
  -p, [--pretend], [--no-pretend]  # Run but do not make any changes
  -q, [--quiet], [--no-quiet]      # Suppress status output
  -s, [--skip], [--no-skip]        # Skip files that already exist

Description:
============
    Generates a new mailer and its views. Passes the mailer name, either
    CamelCased or under_scored, and an optional list of emails as arguments.

    This generates a mailer class in app/mailers and invokes your template
    engine and test framework generators.

Example:
========
    bin/rails generate mailer Notifications signup forgot_password invoice

    creates a Notifications mailer class, views, and test:
        Mailer:     app/mailers/notifications_mailer.rb
        Views:      app/views/notifications_mailer/signup.text.erb [...]
        Test:       test/mailers/notifications_mailer_test.rb

A basic call to rails generate mailer

A basic call to rails generate mailer looks like this —

rails g mailer NAME [method method] [options]

Here we're using the rails g abbreviation, and we can pass the following options —

  • NAME denotes the name of the mailer [required].
  • [method] is an optional list of methods.
  • [options] is an array of additional flags and configurations.

For instance, to generate a mailer called NotificationsMailer with 3 methods — signup, forgot_password and invoice, you would run —

bin/rails g mailer NotificationsMailer signup forgot_password invoice

Executing the above command will scaffold a NotificationsMailer with methods for signup, forgot_password, and invoice. It will also create your mailer views (.html.erb and .text.erb), as well as tests.

When I ran that command in my Rails 7.1 test app, I got the following output —

❯ bin/rails g mailer NotificationsMailer signup forgot_password invoice
      create  app/mailers/notifications_mailer.rb
      invoke  tailwindcss
      create    app/views/notifications_mailer
      create    app/views/notifications_mailer/signup.text.erb
      create    app/views/notifications_mailer/signup.html.erb
      create    app/views/notifications_mailer/forgot_password.text.erb
      create    app/views/notifications_mailer/forgot_password.html.erb
      create    app/views/notifications_mailer/invoice.text.erb
      create    app/views/notifications_mailer/invoice.html.erb
      invoke  rspec
      create    spec/mailers/notifications_mailer_spec.rb
      create    spec/fixtures/notifications_mailer/signup
      create    spec/fixtures/notifications_mailer/forgot_password
      create    spec/fixtures/notifications_mailer/invoice
      create    spec/mailers/previews/notifications_mailer_preview.rb

Note: tailwindcss and rspec are getting invoked here, since I had them setup in my test app. That may be different for you, so my output from rails g mailer might not match yours. That's OK!

The NotificationsMailer itself looks like this —

class NotificationsMailer < ApplicationMailer
  def signup
    @greeting = "Hi"
    mail to: "[email protected]"
  end

  def forgot_password
    @greeting = "Hi"
    mail to: "[email protected]"
  end

  def invoice
    @greeting = "Hi"
    mail to: "[email protected]"
  end
end

rails generate mailer also supports a couple of options/flags we can pass. We can use them to tweak the behaviour of the mailer geneator, and I go into detail on them all further down.

As an example, you can pass the -e flag to railg g mailer specify a different templating laguage, and -t to specify the test framework -

# Generating a mailer with a custom template engine and test framework
rails g mailer PaymentsMailer invoice receipt failed success -e=slim -t=minitest

This command will generate a new mailer,PaymentsMailer, which uses slim for templating, and minitest for testing.

Optional Parameters for rails generate mailer

As I mentioned above, there are a few options we can pass to rails generate mailer (~8 in total). These let us tweak the behaviour of the generator, including skipping namespaces, adjusting the template engine, doing a dry run and more.

Namespace Skipping

[--skip-namespace], [--no-skip-namespace]

This option is related to Rails Engines, and let's you skip automatically applying a namespace to a mailer you generate inside an engine.

Suppose you have an isolated engine named Shop, and you run the following command without the --skip-namespace flag:

bin/rails g mailer Receipt confirmation -e=erb

The generated mailer will be namespaced as Shop::ReceiptMailer.

class Shop::ReceiptMailer < ApplicationMailer
...
end

If you use the --skip-namespace flag, the mailer will be generated outside the Shop:: namespace, just as ReceiptMailer.

Collision Check

[--skip-collision-check], [--no-skip-collision-check]

Collision check is a precautionary measure to avoid overwriting existing files. By default, Rails will halt your generator if it's about to overwrite existing files.

You can use --skip-collision-check to bypass this behaviour.

Template Engine

-e, [--template-engine=NAME]

Rails offers the flexibility of using various template engines (ERB, HAML, Slim).

By default the rails g mailer command will use the generator defined inside config/application.rb. You can use the -e flag to overwrite the default, if you wish.

rails g mailer NotificationsMailer -e=haml

Test Framework

-t, [--test-framework=NAME]

Again, Rails will use the existing test framework for it's generators. You can use the -t flag to overwrite this —

rails g mailer Notifications -t=minitest

Runtime options

All Rails generators also have a couple of runtime flags you can pass. These are —

  • -f, [--force] — similar to --skip-collision-check from above, --force allows rails generate mailer to overwrite any files that already exist.
  • -p, [--pretend], [--no-pretend] — this flag let's you do a dry-run of your rails generate command. Rails will print out the files it would have created, but nothing will actually be created.
  • -q, [--quiet], [--no-quiet] — this flag suppresses all console output from the rails generate command.
  • -s, [--skip], [--no-skip] — similar to --force, this flag will skip generating files that already exist.

Conclusion

I hope you found this article usefule! Using rails generate mailer is a handy way to quickly spin up new mailers in your Ruby on Rails apps.

If you use ActionMailer a lot to send emails in your Ruby on Rails apps, you'll also probably love RailsNotes UI, a collection of email templates and components for ActionMailer.