mirror of
https://github.com/jbranchaud/til
synced 2026-07-02 15:49:44 +00:00
Add Halt ActionMailer Delivery With Callback as a Rails TIL
This commit is contained in:
@@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/).
|
||||
|
||||
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
||||
|
||||
_1795 TILs and counting..._
|
||||
_1796 TILs and counting..._
|
||||
|
||||
See some of the other learning resources I work on:
|
||||
|
||||
@@ -1175,6 +1175,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Get The Column Names For A Model](rails/get-the-column-names-for-a-model.md)
|
||||
- [Get The Current Time](rails/get-the-current-time.md)
|
||||
- [Grab A Random Record From The Database](rails/grab-a-random-record-from-the-database.md)
|
||||
- [Halt ActionMailer Delivery With Callback](rails/halt-action-mailer-delivery-with-callback.md)
|
||||
- [Handle Named Arguments In A Rake Task](rails/handle-named-arguments-in-a-rake-task.md)
|
||||
- [Hash Slicing](rails/hash-slicing.md)
|
||||
- [Ignore Poltergeist JavaScript Errors](rails/ignore-poltergeist-javascript-errors.md)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Halt ActionMailer Delivery With Callback
|
||||
|
||||
`ActionMailer` supports callbacks, similar to `ActiveRecord`, like
|
||||
`before_deliver` and `after_delivery`. We can hook into the `before_deliver`
|
||||
callback to interrupt the delivery of an email that shouldn't go out.
|
||||
|
||||
Here's the scenario: you schedule a bunch of payment reminders to go out to your
|
||||
customers that still need to make their latest payment. Let's say the daily job
|
||||
that schedules all of these reminders runs in the middle of the night, but
|
||||
schedules the emails to land in inboxes at a more reasonable time, like 10am.
|
||||
Between the time that the email is scheduled and it gets processed for delivery,
|
||||
a customer makes their payment. In that case, we no longer want to send that
|
||||
person an email reminder.
|
||||
|
||||
To handle this scenario, we can have a `before_deliver` callback that checks the
|
||||
user's balance and raises `:abort` to halt the callback execution chain,
|
||||
effectively preventing the email from going out. We can even scope the callback
|
||||
to just the actions we care about using the `if` option and checking the
|
||||
`action_name`.
|
||||
|
||||
```ruby
|
||||
class UserMailer < ApplicationMailer
|
||||
before_deliver :abort_if_payment_is_current,
|
||||
if: -> { action_name.in?(%w[payment_reminder past_due_invoice]) }
|
||||
|
||||
def payment_reminder
|
||||
# ...
|
||||
end
|
||||
|
||||
def past_due_invoice
|
||||
# ...
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def abort_if_payment_is_current
|
||||
if @user.check_latest_balance.zero?
|
||||
raise :abort
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
See [Action Mailer
|
||||
Callbacks](https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-callbacks)
|
||||
for more details.
|
||||
Reference in New Issue
Block a user