Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

Railsのnew_framework_defaultsとの向き合い方

こんにちは、ぽっけです。マネーフォワード クラウド会計Plusでエンジニアをしています。

この記事ではRailsのnew_framework_defaultsとの向き合い方を整理します。私は最近Railsアップグレード業をしています。その中でこの設定との向き合い方を考える機会があったため、それを記事にしたためました。

new_framework_defaults とは

まずはnew_framework_defaultsとは何か、について説明します。

この記事では便宜上、以下の2つの要素をまとめてnew_framework_defaultsと表現しています。

  • Rails::Application::Configuration#load_defaultsメソッド
  • config/initializers/new_framework_defaults_*.rb ファイル

これらはRailsのアップグレードをよりスムーズに行うために用意されています。

では、これら2つの要素についてより詳しく見ていきましょう。

Rails::Application::Configuration#load_defaults

load_defaultsメソッドは指定したバージョンでのデフォルトの設定を読み込むメソッドです。実際にはconfig/application.rbに次のように書かれているでしょう。

module AppName
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0

この設定により、rails gemのバージョンに関係なく、Rails 7.0のデフォルト設定がこのアプリケーションで有効となります。

この値はrails newをしたときのrails gemのバージョンが指定されます。またrails gemのアップデート時にbin/rails app:updateをしても更新されません。このバージョンを上げる場合は手で編集する必要があります。

config/initializers/new_framework_defaults_*.rb

これらのファイルは、Railsのマイナーバージョン以上をアップグレードするたびに作られます。例えばRails 6.1から7.0にアップデートした場合、config/initializers/new_framework_defaults_7_0.rbbin/rails app:updateによって作成されます。

生成時点ではこのファイルの内容はすべてコメントアウトされています。つまり、読み込んでも何も起きません。

このファイルでは、該当のRailsのバージョンで、デフォルト値に変更があった設定項目がコメントアウトされています。コメントアウトされたコードは、新しいRailsのバージョンでの設定値を設定するコードです。そのため、コメントアウトを解除することで新しい設定値を有効にできます。

この2つがどう組み合わさるか

この2つを組み合わせると、Railsのアップグレードがスムーズになります。Rails 6.1から7.0へのアップデートを例に、具体的な挙動を見てみましょう。

まず、Railsのバージョンを6.1から7.0に上げて、bin/rails app:updateコマンドを実行します。するとconfig/initializers/new_framework_defaults_7_0.rbが生成されます。この段階では各種設定項目の値はRails 6.1のままです。なぜならばload_defaultsには6.1が渡されたままで、new_framework_defaults_7_0.rb もすべてコメントアウトされているためです。

実際にRails 7.0から変更された設定項目を反映するには、load_defaults7.0を渡すか、 new_framework_defaults_7_0.rbのコメントを外す必要があります。

この機能によってRailsをアップデートするタイミングと、新しいバージョンの設定項目を有効にするタイミングを分けられるようになります。これによってRailsアップデート時の差分を減らせます。

new_framework_defaultsとの向き合い方

ではこの設定はどのように変えていけば良いのでしょうか。 Railsをアップデートした後、次のように設定を変えていくのが良いと私は考えています。

  1. Rails のアップデートが一通り完了する (例: Rails 6.1をRails 7.0にアップデートする)
    • アップデート作業では、new_framework_defaults_X_Y.rbは変更しない
  2. new_framework_defaults_X_Y.rb の項目を1つ1つ精査して、次のどちらかの対応をする
    • 新しい設定を有効にできる場合、コメントアウトを外して有効にする
    • 新しい設定を有効にするのが難しい場合、new_framework_defaults_X_Y.rb からは記述を削除して、config/application.rbconfig/initializers/下の他のファイルに内容を移す
  3. new_framework_defaults_X_Y.rb の設定項目すべてに対応できたら、このファイルを削除し、config/application.rbconfig.load_defaults の引数を更新する

以下で詳細を見ていきます。

1. Rails のアップデートが一通り完了する

まずはRailsのアップデートが完了した状態にしましょう。この記事ではRailsの詳しいアップデート方法については説明しません。

なお、この段階ではload_defaultsnew_framework_defaults_X_Y.rb ファイルの編集は必要ありません。この段階で変更することもできますが、一度に行う変更を少なくするため、以降のタイミングでの変更をおすすめします。

2. new_framework_defaults_X_Y.rb の項目を1つ1つ精査する

Railsのアップデートが完了したら、new_framework_defaults_X_Y.rbの項目を1つ1つ精査して対応しましょう。このときの対応は、新しいRailsの設定を使うかによって2つに分かれます。

なお設定項目についてはコメントで説明されています。詳細な説明へのリンクがある場合も多いので、それを見ながら設定内容について検討すると良いでしょう。

各設定はそれぞれ独立して変更できます。デプロイをできるだけ細かくしたい場合は、設定項目を1つずつ有効にしてデプロイすると良いでしょう。

新しい設定を有効にできる場合

新しい設定を有効にできる場合は、new_framework_defaults_X_Y.rbファイル内のコメントアウトを解除し、設定を有効にします。

このファイルにコメントアウトで書かれている設定は新しいバージョンのデフォルトとなる設定です。そのため、このコメントアウトを解除することで、新しい設定が有効になります。

新しい設定を有効にできない場合

アプリケーションの都合で新しい設定を有効にできないこともあるでしょう。そのような場合には現状の設定を維持するため、現時点での設定値を明示的に設定するコードを追加します。

現状の設定値を確認して、その値をconfig/application.rbconfig/initializers/下の適当なファイルに書き出します。なおconfig/application.rb内に追記する場合には、必ずconfig.load_defaults よりも下に追記してください。

設定を書き出したら、new_framework_defaults_X_Y_.rbからは、コメントアウトされている設定を消してしまいましょう。

この変更は、暗黙的にされていた設定を明示的に設定するだけです。そのため、アプリケーションの挙動を変更しません。この次の段階で必要な設定となります。

3. 設定項目すべてに対応できたら、このファイルを削除し、config/application.rbconfig.load_defaults の引数を更新する

ここまででnew_framework_defaults_X_Y.rb のコメントアウトされた設定項目がすべて対応されました。つまりこのファイルの設定項目すべてに対して、コメントアウトを外すか別の場所に移すかの対応が完了しました。

その状態になったら後はいよいよ仕上げです。new_framework_defaults_X_Y.rb ファイルを削除し、config/application.rb内のconfig.load_defaultsの引数のバージョンを、アップデート後のRailsのバージョンに更新しましょう。

この操作はアプリケーションの挙動を変更しません。今までの変更でload_defaultsを更新したときの影響がなくなるようにしたためです。そのためこのステップは比較的安全に行えます。

この方針の狙い

最後にこの記事の方針の狙いをかんたんに説明します。

アップデートのプロセスを細かく分けられること

Railsのアップデートと、設定の変更を分離できます。また設定の変更も、項目ごとに変更できます。

そのため変更の単位がなるべく小さくなり、デプロイやPull Requestの単位を小さくすることができます。

完了後、余計なファイルが残らないこと

私はnew_framework_defaults_X_Y.rbは「アップデート移行措置のためのファイル」と捉えました。このファイルはアップデートのためのTODOリストとして使用し、完了後は削除します。

このように捉えると、アップデート作業完了後は不要なファイルを残すことがなくなります。

状況がわかりやすいこと

設定項目を編集している間、 new_framework_defaults_X_Y.rbには「対応が必要な項目」のみがコメントアウトされて残ります。

つまり、変更作業はコメントアウトされた項目を1つ1つ対応するだけで良いです。コメントアウトされた項目がなくなれば作業を完了とみなせます。

このようにnew_framework_defaults_X_Y.rb をTODOリストとして使うことで、対応状況がわかりやすくなりました。

まとめ

この記事では、Railsアップデート時に変更される設定項目への対応方法を解説しました。Railsアップデートの際にこの記事を思い出していただければ幸いです。また既存のコードでload_defaultsメソッドに古いバージョンが設定されていたら、そのバージョンを最新まで上げる作業にもこの記事が役立つでしょう。

参考リンク


マネーフォワードでは、エンジニアを募集しています。 ご応募お待ちしています。

【会社情報】 ■Wantedly株式会社マネーフォワード福岡開発拠点関西開発拠点(大阪/京都)

【SNS】 ■マネーフォワード公式noteTwitter - 【公式】マネーフォワードTwitter - Money Forward Developersconnpass - マネーフォワードYouTube - Money Forward Developers