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 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).
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.
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.
Comments
Simple and clean tutorial. Very useful thanks!
Hi, Useful info. Is it possible to avoid an exiting tables creation. e.x : Users already there. But again i tried to run migrations for new incoming tables. Normally we get "users table already exists", Is it possible to avoid in this?.
Well done. Clear, simple, and to the point.
Great, this was exactly what I was looking for.
Add comment