Stripping down Rails 3.1: Using only the database migrations

November 23, 2011


This post was originally published in the Rambling Labs Blog on November 23, 2011.


The current project I’m working on is not using Ruby on Rails, but I still want to use ActiveRecord Migrations for the database changes.

There are some options out there for this, and most people that I read about and had this issue just use the activerecord gem and set up their rake tasks.

I don’t want to write my own rake tasks, since I feel that I would be reinventing the wheel. So what did I do? I created a new rails application, and stripped it down, removing everything that is not needed to run the migrations.

First, I created a rails application called ‘deploy’ on the root folder of the application with:

rails new deploy

Then, I removed all the directories in the deploy folder, except for these:

  • config
  • db
  • lib
  • log
  • script

So far so good. The only uncomfortable thing now is that I have to enter to the deploy directory to run bundle install or rake db:migrate. To solve this issue, I did the following:

I added this Gemfile to the root directory of the application:

source 'http://rubygems.org'
gem 'git-deploy'

gemfile = File.open(File.join(File.dirname(FILE), ‘deploy’, ‘Gemfile’)) eval gemfile.read

And this Rakefile as well:

rakefile = File.open(File.join(File.dirname(__FILE__), 'deploy', 'Rakefile'))
eval rakefile.read.gsub(/config/, 'deploy/config')

task :generate do
  arguments = ARGV.find { |a| a.start_with?('GENERATE=') }
  arguments = arguments.split('=')[1] unless arguments.nil?
  sh "cd deploy; rails generate #{arguments}" unless arguments.nil? or arguments.empty?
end

db_tasks_file = File.open(File.join(File.dirname(__FILE__), 'deploy', 'lib', 'tasks', 'db.rb'))
db_tasks = db_tasks_file.read
namespace :db do
  namespaces = [:test, :production]
  namespaces.each do |name|
    namespace name do
      eval db_tasks.gsub(/{environment}/, name.to_s)
    end
  end
end

This is the lib/tasks/db.rb being included in the Rakefile:

tasks = [:create, :drop, :migrate, :rollback, :version, :seed, :setup]
tasks.each do |name|
  task name do
    sh "rake db:#{name.to_s} RAILS_ENV={environment}"
  end
end

As you can see I added some rake dynamic tasks to manage the migrations in the development, test and production environments from the root directory of the application.

Now, I can run bundle install and rake whatever from my usual working directory.

That’s all folks!