A naming convention for ActionMailer emails

One of the great things about Ruby on Rails is its philosophy of Convention over Configuration. Simply put, this means that developers are encouraged to name and organise their code in specific ways, and to stick to these naming principles wherever possible. The benefit of CoC is that developers spend less mental energy trying to make decisions about things like “where should I store my database schema?”, so they can spend more mental energy on building a great product.

In Rails apps, emails are typically sent by a library called ActionMailer. While ActionMailer is an excellent tool for the job, there’s no common convention in the Rails community on how to name mailer classes and methods. In this post, I’ll share with you the convention I’ve been using on projects I’ve worked on recently.

The essence of a mailer

To develop a naming convention, we must first reflect on how our code is being used, and look for some common patterns that apply to most use cases. In doing so, I’ve realised that most mailers can all be boiled down to these common features:

Recipient
The recipient is the entity that will receive the email. This will normally be a person, but it could also be another app or remote service that receives email inputs. Recipients might be your service users, customers, internal admins, or unauthenticated visitors to your website.
Resource
Emails are usually sent out to provide information about a specific resource or domain concept within the system. In other words, emails are usually sent about something relevant to some thing. An article has been published, a subscription has lapsed, a purchase has been completed. These will often be the models that you’ve defined in your code, but they might also be more abstract concepts (like a password reminder).
Change
Transactional emails don’t just spontaneously fire off. They’re usually sent in response to an event or some change that’s happened within the system. An example could be when some resource is created, updated, cancelled, or renewed.
Intention
Services email people for different reasons, which I’ve called the intention. In practice, using this convention, I’ve only ever come across four different intentions when sending emails: notification, confirmation, warning, and provision. You might discover more in your own use-cases, but I haven’t needed more than these in the past few months.

By identifying these common patterns within our mailers, we can now try to establish a naming convention that communicates what an email is being sent for within our code.

What should you name your Mailer class?

Web applications can sometimes become very large, and the number of different emails that are sent out can easily grow into the dozens, and this sometimes means large ActionMailer classes with dozens of methods defined in them. Most sensible developers will avoid having just one mailer class, and try to split the emails up into separate mailer classes for different purposes.

But this raises the question: what should I name my mailer class? Should I name it based on the recipient? Or the subject matter? Or the namespace within my app? A mixture of these?

My preference is to name ActionMailer classes based on the recipient. This should always be the term you use within your business domain. If you call your customers customers, call your mailer CustomerMailer. If you call your customers “guests”, call your mailer GuestMailer. This makes it very clear who is the intended recipient of a given email.

What should you name your Mailer method?

Just like our class name convention makes it easy to see, at a glance, who the recipient of an email is, your mailer method name should make it clear what the email is about, and why it’s being sent. With this in mind, I use the following naming convention for mailer methods names: #<resource>_<change>_<intention>. To get a feel for this convention, let’s look at a couple of examples:

Example 1:

A visitor to your blog receives an email to notify them that their comment has been approved. In this case, the recipient is a visitor (Recipient), and we’re notifying them (Intention) that their comment (Resource) has been approved (Change).

In this case, we’d define VisitorMailer#comment_approved_notification

Example 2:

An admin of your business receives an email to notify them that a customer payment has failed. In this case, the recipient is an admin (Recipient), and we’re notifying them (Intention) that their payment (Resource) has failed (Change).

In this case, we’d define AdminMailer#payment_failed_notification

Example 3:

A member of your organisation requests a link to reset their password. In this case, the recipient is a member (Recipient), and we’re providing them (Intention) with a password (Resource) reset (Change).

In this case, we’d define MemberMailer#password_reset_provision

Conclusion

So there’s my proposed naming convention for ActionMailer methods. I’ve been using this with great success, and it’s one less thing I have to think about when I’m coding apps.

If you have any thoughts, please feel free to share them with me on Twitter (@morricegavin).

Written by

Photo of Gavin Morrice
Gavin Morrice

Software engineer based in Scotland

Work with me

Need help with some code?

In my free time, I like to help people improve their code and skills on Codementor.
Contact me on Codementor