My all new Ruby Database Script Runner - now with Objects!

Back in December I blogged about how to access ActiveRecord & Migrations outside of Ruby on Rails. It was a little to scriptish for my liking so I've refactored it in a couple of classes instead.

Before you had to copy the code to a new file and add your database migration inside the method. I've now broken this up into a DatabaseScript class that extends ActiveRecord's Migration and has the guts of how and where to run any database commands and then any number of script classes that do the actual work.

The classes that you write on a day to day basis are now similar in style to the standard Rails Migrations:

require 'database_script'

class UniqueScriptName < DatabaseScript
# your migration code goes here
For example I want to update my_table and set all the updated column for all rows to be true:
require 'database_script'

class UpdateMyTable < DatabaseScript
execute('update my_table set updated = true')
If you want to use a specific database connection (rather than one of the standard Rails ones development, testing, production) then add the following method in the above class:
  def self.database_connection_details
adapter: ????
database: ????
username: ????
password: ????
This is what the DatabaseScript class looks like:
require 'active_record'

class DatabaseScript < ActiveRecord::Migration; end

def self.script_name(script_file)
return *script_file.scan(/(.*).rb/).first

def script_class(script_name)

script_name = script_name($0)
require script_name
script_class = script_class(script_name)

# to run this within the context of a Rails app then pass your environment on the command line:
# ruby <script name>.rb development
database_type = ARGV[0]

if database_type.nil?
database_yaml = script_class.database_connection_details
# if you have a Rails project then place your scripts in db/script
database_yaml ='../../config/database.yml')

databases = YAML::load(database_yaml)

database_type = databases.keys[0] if database_type.nil?

Technorati Tags: , , , ,

1 comment:

Rob Baillie said...

Good stuff.

All you need to do now is add 'Pre' and 'Post' condition checking and you're there...