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.
