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:

rails g my_gem:install

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:

    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

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 :

    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

You can define the other examples as you wish.

run the migrations

When your gem is added to some app, you can just do :

    rails g my_gem:install
    rake db:migrate

Hope this helps.