おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

Railsの設定をアップグレードしていく技術

このエントリは SmartHR Advent Calendar 2023の21日目の記事です。

Railsのバージョンを上げる作業は、単に新しいバージョンのgemをインストールするだけでは終わりません。Railsの新しいバージョンに沿った設定項目を確認し、適宜適用していく必要があります。もちろん必ずしもすべての設定を最新にしなければならないわけではありませんが、Railsの新しい設定というのは基本的にそうすることにメリットがあるから作られているわけで、特別な理由がなければ最新の状態にしておきたいものです。

みなさんのRailsアプリケーションのconfig/application.rb には次のような設定があるはずです。

config.load_defaults 6.1

このコードサンプルは引数が6.1なので、Rails6.1デフォルトの設定を適用していることを示しています。これを7.0にするには、まずRails自体を7.0にアップグレードした後に一つずつ必要な設定を足していき、すべての設定を追加した後config.load_defaults 7.0にするのが一番手堅いやり方だと思います*1。

Railsのバージョンアップと設定変更は別々にやったほうが良い

このとき、rails gemのバージョンと一緒にconfig.load_defaultsの引数を変更するのは推奨しません。設定の中にはデプロイのロールバックを困難にするものがあるからです。

例えばRails7.0ではキャッシュの形式を変更するPRがマージされています。このコミットには互換性についての考慮があり、Rails7.0で作られた新しい形式のキャッシュとRails6.1以前に作られた古い形式のキャッシュ両方を読めるようになっています。しかしRails6.1にはこのコミットは含まれていないため、Rails7.0形式で作られたキャッシュをRails6.1のアプリケーションが読むことはできません。

このことから、Rails7.0のアップグレードとキャッシュの形式変更を同時に行った場合、もしデプロイ後しばらくしてから不具合が見つかりRails6.1にロールバックするとRails7.0の間に作られたキャッシュが失われることになってしまいます。キャッシュの形式は変えずにRails7.0のアプリケーションをデプロイし、問題ないことを確認してから設定を変更することで安全にアップグレードを進めることができます。

適用すべき設定一覧を調べる方法

load_defaultsの各バージョンの差分は、コードを見るのが手っ取り早いです。rails app:updateでconfig/initializers/new_framework_defaults_7_0.rbのようなファイルを生成する、という方法もありますが個人的にはコードを直接見るほうが好きです。Railsのアップグレードしたいバージョンをcheckoutし、Rails::Application::Configuration#load_defaultsを見ます。

例えば6.1から7.0にアップグレードしたいときは次のコードが対象になります。

このとき、mainブランチの最新を見るのは推奨しません。例えばconfig.load_defauts 6.1に含まれる active_record.legacy_connection_handling=falseという設定はRails7.1ではデフォルトとなり設定からは削除されたので、mainブランチのコードを参照するとこのような設定を見逃してしまいます。

あとはひたすらやっていくのみ

ここからコードの各設定部分のコミットをgit blameで調べます。コミットコメントや紐づいているPRコメントとコードの差分を読み内容を理解した上で、アプリケーションの修正が必要かを判断していきます。修正が不要であればconfig/application.rbなどに該当の設定を記載してコミットするだけです。

一部の設定は Upgrading Ruby on Rails — Ruby on Rails Guides にも説明が記載されているのでこちらも読むと理解が捗ります。

先程のコードを眺めてみると、config.load_defaultsの引数を6.1から7.0にするためには最大で21個の設定変更が必要になります。プロジェクトによっては利用していないコンポーネントがありもう少し数が減る可能性はありますが、それでも多いことに変わりはありません。逐一設定を調べていくのは大変ですが、普段意識することの少ないRailsの内部仕様について詳しくなるよい機会だとも言えます。頑張ってやっていきましょう*2。

*1:もちろん個人のアプリケーションや、影響範囲がないことが明らかな場合は除きます

*2:もし調べてみたけど内容がよくわからない、とかそもそもやり方がわからないなどあったらお近くの技術顧問にお声がけください