Reputation: 12377
I need to reuse the same method across many migrations. My goal is to avoid code duplication. I tried to do it as shown below, by putting the shared method into file lib/migration_helper.rb
and using include MigrationHelper
in the migrations that use the shared method.
Is there a more standard way of sharing code in different migrations?
In particular, I put the helper file into lib
directory - is this the correct place?
## lib/migration_helper.rb
# Methods shared across migrations.
module MigrationHelper
def my_shared_method
# some shared code
end
end
## db/migrate/do_something.rb
class DoSomething < ActiveRecord::Migration[5.2]
include MigrationHelper
# rubocop:disable Metrics/MethodLength
def up
# some code
my_shared_method
end
# rubocop:enable Metrics/MethodLength
def down
# more code
my_shared_method
end
SEE ALSO:
I got a few ideas from these questions, but they do not fully answer my question:
Custom helper methods for Rails 3.2 Migrations
Rails share code between migrations (aka concerns)
Accessing custom helper methods in rails 3 migrations
This repo has examples of a much more complex version of what I want, with a whole hierarchy of helpers. I need a simpler solution:
https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/database/migration_helpers.rb
https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/db/migrate/20220808133824_add_timestamps_to_project_statistics.rb
Upvotes: 6
Views: 611
Reputation: 1422
just tested, works in rails 7 (and probably earlier version)
What you could do is:
1 - create your file/class kinda wherever
# db/concerns/create_column_alias.rb
module CreateColumnAlias
def create_column_alias(*args)
add_column(*args)
end
end
2 - create an initializer to inject your new helper in the migrations classes (per this gist)
# initializers/extend_migration_with_custom_helpers.rb
require_relative "../../db/concerns/create_column_alias"
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, CreateColumnAlias)
3 - profit.
>$ bin/rails g my_migration
# db/migrate/123345456_my_migration.rb
class MyMigration < ActiveRecord::Migration[7.0]
def change
create_column_alias :tasks, :done, :boolean
end
end
edit
In case you don't want them to be included everywhere, you can skip the serializer and do
require_relative "../concerns/create_column_alias"
# db/migrate/123345456_my_migration.rb
class MyMigration < ActiveRecord::Migration[7.0]
include CreateColumnAlias
def change
create_column_alias :tasks, :done, :boolean
end
end
Though I suggest you not to do that and save you the trouble. It's ok to have all your helpers available at any time even if you don't use them, especially given this has 0 impacts on production rapidity (only the deployment part, and it's super minimal like if you have 100 helpers you will lose only a few seconds)
Upvotes: 2