So, every now and then I get requests from Ted (my boss) to produce figures from PayPerPost.com. The most frequent requests my team and I have automated, by building out a full financial reporting engine inside the application. But, there are still those odd little gems that come through that aren’t automated. I’ve got one sitting in front of me right now actually.
Typically, we’d log onto the production server, run up script/console and bang out some code right there on the live machine. That’s not very smart though. You can’t test what you throw at the console real time, and more to the point there’s no record anywhere of what was done. So, how do you write a console based Ruby script that makes use of ActiveRecord to connect to a live database, just like the Rails app does? I decided to dig in and find out.
Obviously I can’t show you stuff from PayPerPost.com, so lets just work a little hypothetically. Let’s imagine I needed to produce a report of all the users in the system who have a first name beginning with the letter A. My first port of call was to add a new directory to the standard scripts directory in the application. I named it ad_hoc_reports. In there I created a Ruby source file called users_beginning_with_a.rb.
Now, I know that I need to hit the database, and for that we’re going to need ActiveRecord. So, my source file ended up looking like this.
class User < ActiveRecord::Base
end
puts User.count
Simple enough. Running that though gave me a really nasty error
uninitialized constant ActiveRecord (NameError)
So, my script can’t find ActiveRecord. Fair enough, and easy to solve by just adding in a few requires at the top of the source. Looking through some other source it became obvious that I’d need three things. First, I’d need to be able to specify the environment (production, test, development) that the script is running in. That’s fairly easy to do with this line
ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
Next, I’d need to bring in the full environment configs based on the environment I’m running in, as well as basic configuration information.
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
puts User.count
Running that worked just fine. ActiveRecord was subclassed by User, and I was able to call Count on it to get a list of all my Users. So, all that remains is to wrap up the query properly.
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 => ["first_name like ?", "A%"])
puts "There are #{user_count} users in the system beginning with 'A'"
I know this is trivial for many of you out there, but to me it was quite amazing to see how easy it is to write a simple Ruby script that brings in all the rails application goodness for writing handy console based queries. I can see a lot of mileage coming out of this in my own work, maybe even a special querying DSL to make things even simpler (like, by not having to declare the database class that I want to work with).
Hi,
I’m trying to do exactly the same thing. I’m enw to Ruby and Rails. I’m using Rails 1.8, Ruby 1.8.6, and Rubygems 0.9.2.
I get an error when I hit the “require … config/environment” line:
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’: no such file to load — ../../config/../config/envionment} (LoadError)
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
from ./test1.rb:5
I’m just now digging into it but thought I’d post a comment and see if it was “no dahhh” to someone more familar with Rails.
Thanks
Comment by Perry Smith — April 19, 2007 @ 2:30 pm |
Sorry. I mistyped the path. I wasn’t expecting that much of a message for a “file not found” error
Comment by Perry Smith — April 19, 2007 @ 2:37 pm |
Well, subsequent to writing this post I found a much better way of doing things, which is to write a Rake task. You can find all the info on how that works here.
Comment by pwrighta — April 19, 2007 @ 8:27 pm |