Blog
what did i learn today
handling migrations in rails 3 engines

In the process of converting a rails 2.3.* plugin to a rails 3 gem, i bumped into the problem of converting the migrations too. There was some documentation in the rails-guides, but it did not quite do what i wanted. I also found out that in the next version of rails (3.1) there will be support for rake tasks for migrations from engines. What i wanted was that upon invocation of my InstallGenerator, also the migrations would be added, and the user could just do rake db:migrate. So, presume my gem is called MyGem, i want that the following line could be run: [ruby] rails g my_gem:install [/ruby] To achieve this goal, you need to define an InstallGenerator that will add the migrations to the Rails application itself.

create the generator

Create the folder lib\generators\my_gem\install and inside that folder create a file called install_generator.rb with the following code: [ruby] require 'rails/generators/migration' module YourGemName module Generators class InstallGenerator < ::Rails::Generators::Base include Rails::Generators::Migration source_root File.expand_path('../templates', __FILE__) desc "add the migrations" def self.next_migration_number(path) unless @prev_migration_nr @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i else @prev_migration_nr += 1 end @prev_migration_nr.to_s end def copy_migrations migration_template "create_something.rb", "db/migrate/create_something.rb" migration_template "create_something_else.rb", "db/migrate/create_something_else.rb" end end end end [/ruby] The function next_migration_number makes sure each migration gets a unique number (even if they are all added in the same second).

add the migration templates

Inside the lib/generators/my_gem/install/templates add your two files containing the migrations. Let us define the one named create_something.rb : [ruby] class CreateSomething < ActiveRecord::Migration def self.up create_table :abilities do |t| t.string :name t.string :description t.boolean :needs_extent t.timestamps end end def self.down drop_table :abilities end end [/ruby] You can define the other examples as you wish.

run the migrations

When your gem is added to some app, you can just do : [ruby] rails g my_gem:install rake db:migrate [/ruby] Hope this helps.