こんにちは、ぽっけです。マネーフォワード クラウド会計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.rb
がbin/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_defaults
に7.0
を渡すか、 new_framework_defaults_7_0.rb
のコメントを外す必要があります。
この機能によってRailsをアップデートするタイミングと、新しいバージョンの設定項目を有効にするタイミングを分けられるようになります。これによってRailsアップデート時の差分を減らせます。
new_framework_defaultsとの向き合い方
ではこの設定はどのように変えていけば良いのでしょうか。 Railsをアップデートした後、次のように設定を変えていくのが良いと私は考えています。
- Rails のアップデートが一通り完了する (例: Rails 6.1をRails 7.0にアップデートする)
- アップデート作業では、
new_framework_defaults_X_Y.rb
は変更しない
- アップデート作業では、
new_framework_defaults_X_Y.rb
の項目を1つ1つ精査して、次のどちらかの対応をする- 新しい設定を有効にできる場合、コメントアウトを外して有効にする
- 新しい設定を有効にするのが難しい場合、
new_framework_defaults_X_Y.rb
からは記述を削除して、config/application.rb
やconfig/initializers/
下の他のファイルに内容を移す
new_framework_defaults_X_Y.rb
の設定項目すべてに対応できたら、このファイルを削除し、config/application.rb
のconfig.load_defaults
の引数を更新する
以下で詳細を見ていきます。
1. Rails のアップデートが一通り完了する
まずはRailsのアップデートが完了した状態にしましょう。この記事ではRailsの詳しいアップデート方法については説明しません。
なお、この段階ではload_defaults
やnew_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.rb
やconfig/initializers/
下の適当なファイルに書き出します。なおconfig/application.rb
内に追記する場合には、必ずconfig.load_defaults
よりも下に追記してください。
設定を書き出したら、new_framework_defaults_X_Y_.rb
からは、コメントアウトされている設定を消してしまいましょう。
この変更は、暗黙的にされていた設定を明示的に設定するだけです。そのため、アプリケーションの挙動を変更しません。この次の段階で必要な設定となります。
3. 設定項目すべてに対応できたら、このファイルを削除し、config/application.rb
のconfig.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
メソッドに古いバージョンが設定されていたら、そのバージョンを最新まで上げる作業にもこの記事が役立つでしょう。
参考リンク
- https://api.rubyonrails.org/classes/Rails/Application/Configuration.html#method-i-load_defaults
- load_defaultsメソッドのAPIドキュメントです。
- Configuring Rails Applications — Ruby on Rails Guides
- 各設定値がデフォルトでどのバージョンで何にセットされるかが書かれています。
- config.load_defaultsとnew_framework_defaults_x_x.rbの関係を詳しく調べてみた - Qiita
- 今回説明している対象のメソッドの、動作確認を行っている記事です。
- https://railsguides.jp/upgrading_ruby_on_rails.html#フレームワークのデフォルトを設定する
- アップデート方針が書かれています。今回の記事では、このリンク先の内容をより細かく解説しました。
マネーフォワードでは、エンジニアを募集しています。 ご応募お待ちしています。
【会社情報】 ■Wantedly ■株式会社マネーフォワード ■福岡開発拠点 ■関西開発拠点(大阪/京都)
【SNS】 ■マネーフォワード公式note ■Twitter - 【公式】マネーフォワード ■Twitter - Money Forward Developers ■connpass - マネーフォワード ■YouTube - Money Forward Developers