First posted here: How to override/modify rails built-in migration generator? · Issue #53356 · rails/rails · GitHub
background
In our Rails app, we have a folder called plugins
where we can have Rails-like apps related to our main Rails app.
Those include migration, jobs, models, etc.
One of the pieces that are not very well glued together is the migration generation story–Currently, we need to generate via rails g migration_name
a migration file and then move it to the plugins/<plugin-name>/db/migrate
folder.
I’ve read the rails generator guide and ended up creating this .rb
generator:
/lib/generators/rails/plugin_migration_generator.rb
/lib/generators/rails/plugin_migration_generator.rb
# frozen_string_literal: true
require "rails/generators/active_record/migration/migration_generator"
class Rails::PluginMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
class_option :plugin_name,
type: :string,
banner: "plugin_name",
desc: "The plugin name to generate the migration into.",
required: true
source_root "#{Gem.loaded_specs["activerecord"].full_gem_path}/lib/rails/generators/active_record/migration/templates"
private
def db_migrate_path
"plugins/#{options["plugin_name"]}/db/migrate"
end
end
And it works fine for the most part.
Working pictures
--help
command:
running rails g plugin_migration some_migration2 --plugin-name discourse-chat-integration
:
Then I read the overriding rails generators part. The docs mention that you can override/configure the built-in rails generators.
This leads to my question: How to override/modify rails built-in migration generator?
A similar question was asked before in the forum. What I’m looking for is more to extend the options of the generator rather than override completely
Steps to reproduce
in Linux/MacOs
rails new app
cd app
mkdir -p lib/generators/rails
touch lib/generators/rails/migration_generator.rb && curl https://gist.githubusercontent.com/Grubba27/1f764790df4ed7a039c47061890ab063/raw/1dbfff909cd4a621d48d04b4e77b1ddf8c352e4f/migration_generator.rb >> lib/generators/rails/migration_generator.rb
touch lib/generators/rails/plugin_migration_generator.rb && curl https://gist.githubusercontent.com/Grubba27/1f764790df4ed7a039c47061890ab063/raw/1dbfff909cd4a621d48d04b4e77b1ddf8c352e4f/plugin_migration_generator.rb >> lib/generators/rails/plugin_migration_generator.rb
These are the two files from the gists:
# frozen_string_literal: true
require "rails/generators/active_record/migration/migration_generator"
class Rails::PluginMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
class_option :plugin_name,
type: :string,
banner: "plugin_name",
desc: "The plugin name to generate the migration into.",
required: true
source_root "#{Gem.loaded_specs["activerecord"].full_gem_path}/lib/rails/generators/active_record/migration/templates"
private
def db_migrate_path
if options["plugin_name"]
"plugins/#{options["plugin_name"]}/db/migrate"
else
"db/migrate"
end
end
end
# frozen_string_literal: true
require "rails/generators/active_record/migration/migration_generator"
class Rails::MigrationGenerator < ActiveRecord::Generators::MigrationGenerator
class_option :plugin_name,
type: :string,
banner: "plugin_name",
desc: "The plugin name to generate the migration into."
source_root "#{Gem.loaded_specs["activerecord"].full_gem_path}/lib/rails/generators/active_record/migration/templates"
private
def db_migrate_path
if options["plugin_name"]
"plugins/#{options["plugin_name"]}/db/migrate"
else
"db/migrate"
end
end
end
Expected behavior
running the following command
rails g migration foo2 --plugin-name testing
# creates plugins/testing/db/migrate/20241017210353_foo.rb
Actual behavior
rails g migration foo --plugin-name testing
# creates db/migrate/20241017210413_foo.rb
System configuration
Rails version:
Rails 7.1.4.1
Ruby version:
ruby 3.2.2