Most of my work involves grinding out new features for my web-app, but then on monday I came to several items in a row in my backlog notes that were going to be outside this realm. Although I have several specific examples of my own, you could probably think of hundreds of tasks like this: purging database tables, recieving emails into the database, sending users SMS or email notifications based on time-sensitive data, processing batches, generating nightly reports...I'm sure the list goes on and on. What's disturbing is something I saw far too frequently as I was crawling the web for a good solution was this: a random script full of copy-and-paste code that manually loads the rails environment ahead of time (or worse, PIECES of rails). Let me say right now: "Oh god, please don't ever do that". Yes, it works, but there's no REASON to go to that sort of trouble.
There are two ways I know of that you can load the rails environment easily: script/runner, and Rake.
If you're writing a script that you just want to run once, and it needs to hook into your rails app, just write it the way you would inside your application (go ahead and assume the presence of all the rails libraries) and then run it from the home directory of your application like this:
$> ruby script/runner my_script.rb
If you're building something that you want to run frequently, or even at regular intervals, just write the code the way you would in a rails model and package it into a rake task like this (this file goes in the "lib/tasks" directory of your rails app):
namespace :server do
desc 'Send SMS Notifications'
task :send_notifications => :environment do
Notification.find(:all).each do |n|
desc 'Build Batch File'
task :build_batch => :environment do
file = File.new("new_batch.txt","w+");
t = Translator.new()
data_string = t.translate(Notification.find(:all))
desc 'process emails'
task :check_mail => :environment do
Now you can run it any time with the following:
$> rake server:check_mail
or you can have a cron job run it regularly with this entry in your crontab file:
5 0 * * * cd /path/to/your/app && /path/to/your/rake server:check_mail RAILS_ENV='production'