class MyPluginGenerator < Rails::Generator::NamedBase
def initialize(runtime_args, runtime_options = {})
super
@argument = runtime_args.shift
end
def manifest
relative_migration_path = "../../../db/migrate/"
recorded_session = record do |m|
get_migrations.each do | mf |
new_migration_file_name = mf.sub(/^(\d{3})_/,'')
new_migration_file_name.sub!(/\.rb$/,'')
unless migration_exists(new_migration_file_name)
m.migration_template "#{relative_migration_path}/#{mf}", 'db/migrate',
:assigns => { :migration_name => new_migration_file_name.camelize},
:migration_file_name => new_migration_file_name
puts " CREATING #{new_migration_file_name}."
else
puts " exists #{new_migration_file_name}, skipping."
end
end
end
end
protected
# Override with your own usage banner.
def banner
"Usage: #{$0} my_plugin migration"
end
def migration_exists(file_name)
migration_directory = File.dirname(__FILE__) + "/../../../../../db/migrate"
not Dir.glob("#{migration_directory}/[0-9]*_*.rb").grep(/[0-9]+_#{file_name}.rb$/).blank?
end
def get_migrations
migration_files = []
my_plugin_migration_path = File.dirname(__FILE__) + '/../../db/migrate'
Dir.entries(my_plugin_migration_path).sort.each do | migration_file |
if migration_file =~ /^(\d{3})/
migration_files << migration_file
end
end
migration_files
end
end
I place this in the file:
vendor/plugins/my_plugin/generators/my_plugin/my_plugin_generator.rb
To run it, I do:
ruby script/generate my_plugin migration
The generator will copy migrations from vendor/plugins/my_plugindb/migrate to db/migrate. It uses Rails functionality to ensure that the migration files are numbered sequentially starting with my application's next available migration number. If the migration is already in db/migrate, it will be skipped but it will not abort. This means I can add migrations to the plugin and run the generator again without worrying about it overwriting the old migrations.
Most of the work is done in the manifest method. By default, the Rails method migration_template looks for the template in a directory called template. In this case it would be looking for the migration file in vendor/plugins/my_plugin/generators/my_plugin/template which is what my relative_migration_path is relative to. My migration_exists method is basically a cut-and-paste from the Rails source code. I don't know why but they these methods are protected in Rails.
I hope this helps, it's a temporary fix. I'm sure the guys at plugin a week will have plugin_migrations fixed in no time :)