I want to set up an email alert based on a user-given date (I have a “valid-to” variable and I want to send an email alert a few days before the expiry); is there a gem that can do that?
Assuming you’re using a Unix-like system (which for most Ruby programmers is the case, there’s an inbuilt tool which is your friend – cron.
This is a job scheduler that wakes up periodically, invokes a command (normally a shell script) and then goes back to sleep.
There are two possible issues with using cron in your Ruby application, though.
Firstly, the syntax, while not complicated, isn’t immediately obvious.
And secondly, if this periodic task is really important, you want it stored alongside your source code and included as part of your deployment process, so you can’t accidentally forget to set it up.
“whenever” to the rescue
Add this gem to your Gemfile (or however else you manage gems in your project), and add a file into your config folder, called schedule.rb.
Whenever includes a simple syntax for invoking various types of commands in your application – but for the most part, I recommend using a rake task; in a Rails app, that means you can have your full environment loaded for you and access all your code nice and easily; in a non-Rails app, it may be just as well to use the “runner” command to invoke your code directly.
every 1.day, at: ‘3am’ do
Your rake task may look something like this:
namespace :send do
task :daily_notifications => :environment do
In this case, I’m invoking a Command object that finds any users that require a notification sending and invokes a Mailer to send them. The advantage of using a Command like this is this is that often rake tasks go untested, and the first you hear of a bug in them is when the client rings up, saying their emails weren’t sent. By isolating the actual work in a separate class, you can add in a test to make sure you don’t inadvertently break anything six months down the line.
All this is great – but how do you get it on to your production server?
This depends upon your deployment scripts – if you use Capistrano (which is a Ruby-based wrapper over SSH) then the gem includes some Capistrano tasks to do the setup (watch out though, I’ve had a few bootstrap issues where whenever tries to configure itself before it’s finished setting itself up – doing two deployments seemed to fix that).
If you don’t, you just need to invoke the “whenever” command at the right point in your deployment process and all should be well.
And there you have it – make your app work when no-one’s watching and automatically do tasks on a schedule.