Script vs Rake...
Let’s take a real world issue and then examine the best practice solution. I use the term best practice because that’s what I mean to say. Can you load half of Rails into a Ruby script and hack away and copy and paste away for every other script you want to run? Sure. But you’re wasting a crap-ton of energy on something that’s ALREADY PROVIDED FOR YOU. That is Rake. Rake, in the context of your Rails app, has everything you need to write a quick and DRY process that accepts arguments and can run all of your lovely tasks whenever you like. Can you write scripts outside of the context of your app? Sure, but then you may find yourself in a pinch recreating things that you’ve already got at hand or worse loading Rails into Ruby over and over and over again something that rake doesn’t do.
Let’s take an example from a blog that I saw a few weeks ago, here In this example the user is faced with a delima. They want reports generated to give information about how many users are in the system with the last name that begins with the letter A. The user then creates a ruby script that does the following…
ENV[’RAILS_ENV’] = ARGV.first || ENV[’RAILS_ENV’] || ‘development’
require File.dirname(__FILE__) + ‘/../../config/boot’
require “#{RAILS_ROOT}/config/environment”
class User < ActiveRecord::Base
end
user_count = User.count(:conditions =&amp;amp;amp;gt; [”first_name like ?”, “A%”])
puts “There are #{user_count} users in the system beginning with ‘A’”
Yes, there are many things to comment on but first and foremost… this will “work”. It just doesn’t work well. It’s not that the code is bad, it’s just that not following the conventions of Rails can get you into a bind just like this. The convention is Rake. So, let’s rewrite this task in Rake and better yet let’s clean it up a bit too!
First, in our app we’ll add a rake file in lib/tasks called user_count.rake and we’ll add in the code from above written in a much DRYer way…
desc 'a rake task to tell us users by first_name criteria'
task :query_users => :environment do
if ENV["CRITERIA"].nil?
puts 'Please provide CRITERIA'
else
user_count = User.count(:conditions => ['name like ?', "#{ENV['CRITERIA']}%"])
puts "There are #{user_count} users in the system beginning with: #{ENV['CRITERIA']}"
end
end
Because rake tasks can run in the context of your rails app you can easily take advantage of your existing models without randomly forming new ones. I hope this example from the real world will help guide people as we find the best practices of working with Rails day in and day out. As always, please feel free to comment, correct, question as you like!
articleStats
Here are some silly little facts about this Script vs Rake......
article Links
These are the links that appear in this article. They probably don't make sense out of context... but just in case. :)
rsshere
Is there another way to pass arguments to the rake task rather than an environment variable? It seems like that's stretching what environment variables are for - setting a global, environment specific value, rather than feeding it into a script.
Granted, that's just me being picky about it. The rake certainly seems like a better approach.