activerecord-compatible_legacy_migration (0.1.0): Compatible migration file between Rails 4.2 and 5+ https://t.co/k14u4ZXuHt
— RubyGems (@rubygems) August 4, 2016
どんなgemか
同一のmigrationファイルでRails 4.2系とRails 5.0系の両方でいい感じに動くようにするためのgemです
これだけだと分かりづらいので具体例を出します
Rails 4.2系から5.0系へのmigrationファイルの移行について
Rails 4.2系から5.0系に移行する時に、Rails 4.2で作られた既存のmigrationのスーパークラスを下記のように ActiveRecord::Migration
から ActiveRecord::Migration[4.2]
にします
Rails 4時代のmigration
class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.timestamps null: false end end end
Rails 5移行後のmigration
class CreateUsers < ActiveRecord::Migration[4.2] def change create_table :users do |t| t.timestamps null: false end end end
ActiveRecord::Migration
のままでもエラーにはなりませんがログファイルに下記のようなDEPRECATION WARNINGが出ます *1
DEPRECATION WARNING: Directly inheriting from ActiveRecord::Migration is deprecated. Please specify the Rails release the migration was written for: class CreateUsers < ActiveRecord::Migration[4.2]
ユースケース
アプリであればmigrationファイルを上記のように修正すればいいのですが、moutable engineのようにgemの中に内包されてるmigrationファイルをアプリの db/migrate/ にコピーするgemだとそうはいきません。
- gem内のmigrationファイルが
ActiveRecord::Migration
の場合 - gem内のmigrationファイルが
ActiveRecord::Migration[4.2]
の場合
migrationファイルを内包したgemをいくつかメンテしているのですが、Rails 5対応をするために既存のRails 4系のアプリともmigrationファイルの互換性を保つのが割とつらかったのでそれを解決するために作りました
使い方
migrationクラスのスーパークラスを ActiveRecord::CompatibleLegacyMigration.migration_class
にするだけです
class CreateUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def change create_table :users do |t| t.timestamps null: false end end end
ActiveRecord::CompatibleLegacyMigration.migration_class
はRails 5.0以降だと ActiveRecord::Migration[4.2]
を、Rails 5未満だと ActiveRecord::Migration
を返します
Rails 5.0以降でしか使えないmigrationファイルはgemとして配布する時に ActiveRecord::Migration[5.0]
つければいいと思います
おまけ
他のgemはどうやってRails 5対応やってるんだろうなぁと思って試しに devise を見たら [5.0]
の部分をerbで埋め込んでた
- https://github.com/plataformatec/devise/blob/v4.2.0/lib/generators/active_record/devise_generator.rb#L12-L18
- https://github.com/plataformatec/devise/blob/v4.2.0/lib/generators/active_record/templates/migration.rb
gemごとに個別対応するの、つらみある。。。
最後に
gemでmigrationファイルを配布していてRails 4.2系とRails 5.0系を両方メンテする必要が出てきたら是非ご利用ください
*1:コンソールには出ないので注意