Rails migrations are great, they allow continual evolution of database schema. Sometimes, especially when prototyping, I hate to run migrations down and up and load data, just to make small independent change in database table. In this situations I run only specific migration:
ruby script/runner 'require "db/migrate/005_create_blogs"; \n
CreateBlogs.migrate(:down)'
ruby script/runner 'require "db/migrate/005_create_blogs";\n
CreateBlogs.migrate(:up)'
This is much typing (for just one migration at least ;) so here is the rake task to do the same:
namespace :db do
task :migrate_one => :environment do
file = Dir["db/migrate/#{ENV["VERSION"]}_*.rb"].first
require(file)
migration_class = file.scan(
/([0-9]+)_([_a-z0-9]*).rb/)[0][1].camelize.constantize
migration_class.migrate(:down) unless ENV["DIRECTION"] == 'up'
migration_class.migrate(:up) unless ENV["DIRECTION"] == 'down'
end
end
Put this rake task in lib/tasks and you can call it with rake db:migrate_one VERSION=005. This would run migration down and up. You can also add DIRECTION=up or DIRECTION=down to control direction.
Check if target database table is of MyIsam type. You have two options, first is not to use transactional fixtures in tests:
self.use_transactional_fixtures = false
Second and better option is to convert all tables to InnoDB tables. This migration can help converting:
class MyIsam2InnoDb < ActiveRecord::Migration
def self.up
ActiveRecord::Base.connection.tables.each {|t|
execute "ALTER TABLE #{t} TYPE=InnoDB"}
end
def self.down
end
end