I have many Appointment
models that start at various times of the day, either at :00, :15, :30, :45. I'd like to trigger code to send a reminder 1 hour before the event starts. What would be the best way to use a background worker to trigger this? I'm using the clockwork gem as well so I can schedule Sidekiq workers.
The clockwork
gem is for fixed schedule jobs (a replacement for cron). You'll want to use ActionMailer.delay_until
that comes with sidekiq
:
class Appointment
after_create :queue_reminder
def queue_reminder
MyMailer.delay_until(event_time - 1.hour).appointment_reminder(id)
end
end
See sidekiq
docs here: https://github.com/mperham/sidekiq/wiki/Delayed-Extensions
As shock_one mentioned, if you update an appointment with a new date, you'll have to requeue a reminder and cancel the old one. You'll also want to cancel a job if an Appointment
is destroyed.
For that, I'd advise you use sidekiq-status
, and a reminder_job_id
column. Your Appointment
model would then look something like:
class Appointment
before_save :queue_reminder, if: :event_time_changed?
after_destroy :cancel_reminder, if: :reminder_job_id?
def queue_reminder
cancel_reminder if reminder_job_id
self.reminder_job_id = MyMailer.delay_until(event_time - 1.hour)
.appointment_reminder(id)
end
def cancel_reminder
Sidekiq::Status.cancel reminder_job_id
end
end