Rails 6.1 -> 7.0アップグレードのメモ
はじめに
GMOメディア株式会社でプログラミングスクールのポータルサイトの開発をしているkameです。
Rails6.1から7.0にアップグレードしたときの過程を書いていこうと思います。
アップグレードを行った理由
現在サポートされているRailsのバージョンは6.1系以降のため、現在使用しているバージョンがそのうちサポート対象外になることが予想されます。まだサポート期限は発表されていないものの、早めに上げておきたいという気持ちと、Rails7の新しい機能への興味からアップグレードを行いました。
アップグレードの事前準備
アップグレード作業を始める前に、以下のことを行いました。
リリースノート、Railsアップグレードガイド、アップグレード関連の記事を読む
アップグレード作業を始める前に、以下のドキュメントを読んで概要を把握しました。
-
Rails公式のリリースノート
アップグレードでどのような変更点があるのかがわかります。
今回はRails7.0.8に上げたのでRails7.0~7.0.8のリリースノートを読みました。
-
Railsアップグレードガイド(Railsガイド)
アップグレードの方法やバージョンごとのアップグレード時の注意点がわかります。
-
アップグレード関連の記事
上記の資料だけでは詳細な手順がイメージしづらかったため、
実際にアップグレードした方たちが作成した記事を読んで、作業の流れを理解しました。
特に参考にさせていただいた記事は以下です。
gemがRails7に対応しているかの確認 & gemのアップデート
Rails7に対応していない状態のgemのままアップグレードしてしまうと、エラーが発生する可能性があるため事前の確認とアップデートが必要です。
先ほど紹介したRailsアップグレードガイドの他に、RubyGemsや各gemのリポジトリを見に行き、Rails7に対応しているかをチェックしました。
今回は以下のgemの対応を行いました。
- spring (2.1.1)を3.0.0以上にする
- spring-watcher-listen (2.0.1)を2.1.0にする
各種設定ファイルの変更点を確認する
アップグレードのコマンドを叩くと、複数の設定ファイルの変更点を取り込むかどうかを[Ynaqdhm]形式で決めていくのですが、変更の内容を事前に確認できるRailsDiffという便利なサイトがあります。
普段の開発でRailsの設定の内容をあまり意識していない場合、アップグレードコマンドを叩いた時に変更を取り入れるかを聞かれても判断できないと思います。(私はそうでした)
RailsDiffを使えば変更の内容を事前に調べられるのでとても便利でした。
また、変更前・変更後それぞれのバージョンを選んでそれらの差分を確認できるのも良いポイントでした。
アップグレード手順
事前準備が終わったらアップグレードを始めます。
bin/rails app:update
の実行
bin/rails app:update
コマンドを実行すると、
configディレクトリ下の設定ファイル等の変更を提案してくるので[Ynaqdhm]形式で答えます。
こちらは先ほどRailsDiffで変更を受け入れるかを事前に調査していたのですぐに判断できます。
実行後は新たな設定ファイルが作成されたり、既存の設定ファイルの内容が変更されます。
rails db:migrate
の実行
migrationコマンドが実行できることを確認するために、rails db:migrate
を実行しました。
実行後、schema.rb
に以下の変更がありました。
- Railsバージョンの変更
- ActiveRecord::Schema[6.1].define(version: 2023_12_07_015208) do
-
+ ActiveRecord::Schema[7.0].define(version: 2023_12_07_015208) do
- timestampフィールドに
precision: nil
が追加された
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
Rails7より前ではprecision
を指定していない場合、DBのデフォルトのprecision
が適用されていたそうです(今回はこのパターン)。
Rails7からはprecision
にnil
を指定するとDBのデフォルトが適用されるようになります。
参考にした記事
config/initializers/new_framework_defaults_7_0.rb
の設定
config/initializers/new_framework_defaults_7_0.rb
はアップデートをするたびに自動で作成されるファイルで、新しいRailsのバージョンでの設定値を設定するコードが記載されています。
生成された時点ではファイルの内容はすべてコメントアウトされていて、コメントアウトを解除すると設定が適用されます。
こちらの記事にそのファイルの説明が詳しく記載されていました↓
また、こちらの記事ではRails7のconfig/initializers/new_framework_defaults_7_0.rb
の書く項目の説明がされていてわかりやすかったです↓
動作確認
アップグレードコマンドの実行や設定ファイルの変更が完了したら、動作確認を行いました。
ローカルでの動作確認
以下の動作を確認しました。
-
bundle i
を実行する -
rails c
を起動する -
rails db:migrate
を実行する -
rails db:rollback
を実行する - サーバーを起動する
- 主要なページが閲覧できる
- サービスの中で重要な動作が実行できる
- テストが全てパスする
テスト環境での動作確認
ローカル環境での動作確認が問題ないことが確認できたら、テスト環境にデプロイして動作を確認しました。
コードレビューをしてもらう
動作確認が終わったら、PRを作成してチームメンバーにコードレビューをしてもらいました。
変更した設定について質問を受けたりすることで理解が深まったり設定の見直しができるので、年次に関わらず必ずレビューしてもらった方がいいと思いました。
本番環境にデプロイ&動作確認
テスト環境での全ての確認作業が完了したら、PRをマージして本番環境にデプロイします。
何かトラブルがあった時にすぐにアップグレード前の状態に戻せるように、マージボタンを押した後にすぐにリバートのPRを作成しました。
また、デプロイ直後は可能な範囲で手動テストを行いました。
さらにデプロイした後の数日間はログやサーバーのリソース状況をチェックし、問題が発生していないか監視しました。
アップデート・デプロイ作業で詰まったところ
spring gemのアップグレード
Rails7ではspring gem
のバージョンを3.0.0以上にアップグレードする必要があり、現在使用しているバージョンは2.1.1だったため3.0.0以上に上げようとしました。
しかし、springに依存しているspring-watcher-listen
というgemも使用しており、こちらはspring 3.0未満を要求していました。そのためspringのみを上げようとするとエラーが出ました。
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0)
対応としては、Gemfileで両方のバージョンを書き換えてbundle install
を実行することでエラーを回避できました。
gem 'spring', '~> 4.1', '>= 4.1.1'
gem 'spring-watcher-listen', '~> 2.1.0'
gemの依存関係はこちらで調査しました↓
テスト実行時のDEPRECATION WARNINGの発生
bin/rails app:update
の実行後にテストを実行したところ、エラーは出なかったものの以下のようにDEPRECATION WARNING
が多数表示されました。
# Running:
.DEPRECATION WARNING: Integer#to_s(:〇〇) is deprecated. Please use Integer#to_fs(:〇〇) instead. (called from show at /Users/xxxxx/workspace/リポジトリ名/app/controllers/xxxxx/xxxxx_controller.rb:24)
DEPRECATION WARNING: Integer#to_s(:〇〇) is deprecated. Please use Integer#to_fs(:〇〇) instead. (called from show at /Users/xxxxx/workspace/リポジトリ名/app/controllers/xxxxx/xxxxx_controller.rb:24)
.DEPRECATION WARNING: Integer#to_s(:〇〇) is deprecated. Please use Integer#to_fs(:〇〇) instead. (called from show at /Users/xxxxx/workspace/リポジトリ名/app/controllers/xxxxx/xxxxx_controller.rb:24)
DEPRECATION WARNING: Integer#to_s(:〇〇) is deprecated. Please use Integer#to_fs(:〇〇) instead. (called from show at /Users/xxxxx/workspace/リポジトリ名/app/controllers/xxxxx/xxxxx_controller.rb:24)
Rails7ではto_sの引数にシンボルでフォーマットを指定すると、DEPRECATION WARNING
が発生するようになったことが原因でした。
WARNINGにも書いてある通り、to_s(:〇〇)
をto_fs(:〇〇)
に置換したことでこの表示はなくなりました。
テスト環境へのデプロイ時のエラー
テスト環境へのマイグレーションを実行する際にエラーが起きました。
/app/bundle/ruby/3.2.0/gems/fog-google-1.19.0/lib/fog/google/shared.rb:197:in `read': No such file or directory @ rb_sysopen - /app/google_credentials_for_app.json (Errno::ENOENT)
from /app/bundle/ruby/3.2.0/gems/fog-google-1.19.0/lib/fog/google/shared.rb:197:in `process_key_auth'
from /app/bundle/ruby/3.2.0/gems/fog-google-1.19.0/lib/fog/google/shared.rb:73:in `initialize_google_client'
エラー内容は「ディレクトリにファイルがない」というものです。
原因はconfig/environments/配下のファイルにあった以下の設定でした。
config.eager_load = true
上記のようにeager_load
をtrueにすると、controllerやmodelなどのclass名がすべて事前に(rails serverが起動するタイミングで)読み込まれますが、マイグレーションの際に必要ないものまで立ち上がり、存在しないファイルを探してしまっていました。
falseに設定するとテストDBのマイグレーションが正常に実行されました。
おわりに
以上がRailsアップグレードの一連の流れでした。
私はプログラミングスクールを卒業後、エンジニアとして働き始めて8ヶ月目でこちらのアップグレード作業に携わらせていただきました。
入社してから行なった業務の中でも難易度が自分にとっては高く、規模が大きめだったのでひたすら調べながら&ブランチを何度も切り直しながら行いました。
調べても自分では解決できない時も多々ありましたが、チームメンバーの手厚いサポートのおかげで乗り越えることができました。(みなさんいつも助けていただきありがとうございます!)
また、今まではconfig配下のRailsの設定について意識せずに開発を行なっていましたが、今回アップグレード作業を行なったことでどんな設定があるのかを知ることができ、とてもいい経験になりました。
自分はまだまだ経験が浅いため機能や設定について詳しく取り上げられませんでしたが、もしこれからRails7にグレードアップする方がいれば少しでも参考になればいいなと思います。
Discussion