Typical Rails convention will tell you to send email like using the ActiveMailer API using #deliver_later
. This is not a very good idea, and let me tell you why.
This kind of mailer would typically be implemented like so:
Next: Let's look at how this can cause problems.
If you follow Rails best practices, you'd be using #deliver_later
to send email in the background. This is great for performance, but that means you have to start thinking asynchronously. The code above is written in a very synchronous style and will fail in certain conditions. Consider this scenario:
[email protected]
, by creating a new Post
.Post
is deleted.@post
is nil.Next: So how can we fix this?
Instead of passing Rails models or record ID's, pass a fully-loaded plain hash of everything the mailer needs to send the email. Consider something like this instead:
The mailer will now not need to hit the database to fetch any data, eliminating any race conditions. Even if the post is modified or deleted later on, the email will still send just fine.