入社前だけど3,000万MAUのサービスをRails8.0にアップグレードしちゃいました
はじめに
株式会社マイベストに2025年度入社予定のYagiです!一年前からバックエンドエンジニアとして内定者インターンに取り組んでいます。今回、マイベストで使用されているRuby on Railsを7.2から8.0にアップグレードしたので、その手順や遭遇した問題点などをまとめています。
アップグレード手順
- Gemのバージョンを最新にする
- アップデートタスクを実行
- 新たに発生するようになったエラーへの対処
- フレームワークのデフォルトを設定
- QA環境にデプロイして動作確認する
- 本番環境にデプロイ
Gemのバージョンを最新にする
Railsのアップグレード作業に入る前に、Rails以外のGemバージョンを最新にします。これは、Rails本体の変更だけでなく、依存するGemの変更による影響も最小限に抑えるためです。
マイベストでは、Dependabotを導入し、普段からGemの依存関係を管理しています。そのため、差分もあまりなく、比較的スムーズに最新バージョンへの更新作業を行うことができました。
各GemのChangelogで破壊的変更を確認し、プルリクエスト上でも表にまとめておきます。
開発環境・テスト環境のGemと本番環境のGemでリリースを分けることで、リリース時の影響を最小限に抑えました。
bundle update -g development -g test
アップデートタスクを実行
Gemのアップデートが完了したので、Railsを8.0に上げていきます。
- gem 'rails', '~> 7.2'
+ gem 'rails', '~> 8.0'
$ rails app:update
設定ファイルなど、手作業での修正が必要な箇所は、Rails Diffなどのサイトで差分を確認しながら慎重に作業し、意図しない変更や設定ミスを防ぎました。
新たに発生するようになったエラーへの対処
Railsのバージョンアップに伴って、新たなエラーや警告が追加されたので、該当箇所を修正します。
ルーティングエラー
↓のリリースにより、ルーティング設定において、存在しないメソッドをonly
またはexcept
オプションで使用した場合、ArgumentErrorが発生するようになったようです。
エラーメッセージに従ってonlyオプションを書き換えました。
- resource :user, only: :none do
+ resource :user, only: [] do
RSpecエラー
次に、CIのRSpecテストでは2種類のエラーが大量に発生していました。
↓のリリースにより、STATS_DIRECTORIES
の定義方法が変わったことで、2回目以降の実行時はエラーを吐くようになりました。
挙動をコンソールで確認
そして、このSTATS_DIRECTORIES
が定義されているファイルはtasksディレクトリ内に配置されていたため、タスクの過剰な読み込みが発生していると予測。
確認したところ、各テストグループの開始前に毎回タスクがロードされていました。
テストスイートの開始時に一度だけ行えば良いので、before(:suite)
に移します。
config.before(:suite) do
+ Rails.application.load_tasks
end
config.before(:all) do
- Rails.application.load_tasks
end
やはりこれが原因でした。
また、各テストファイルでもさらにタスクをロードしてしまっていたので、まとめて削除します。
RSpec.describe 'hoge_task' do
- before(:all) do
- @rake = Rake::Application.new
- Rake.application = @rake
- Rake.application.rake_require 'tasks/hoge'
- Rake::Task.define_task(:environment)
- end
# ...
end
フレームワークのデフォルトを設定
Rails8.0では新たに3つのデフォルト設定が追加されました。
Rails.application.config.active_support.to_time_preserves_timezone = :zone
Rails.application.config.action_dispatch.strict_freshness = true
Regexp.timeout = 1
どれも軽微な変更ですが、対応が必要ないことが確認できたらload_defaults
を上げて設定を適用します。
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
- config.load_defaults 7.2
+ config.load_defaults 8.0
# ...
end
また、レビューしやすいよう、これらの設定について概要や挙動の違いをNotionにまとめました。
↓詳細はこちら
デフォルト設定の変更点
active_support.to_time_preserves_timezone = :zone
1. 概要
to_time
メソッドがタイムゾーンを保持するか、UTCオフセットを保持するかを制御します。
設定オプション:
-
:zone
: タイムゾーンを保持 -
:offset
: UTCオフセットを保持 -
false
: ローカルシステムのUTCオフセットに変換
以前までデフォルトで :offset
だったのが、8.0で:zone
になりました。
コンソールでの両者の挙動:
:offset (7.2 以前)
:zone (8.0 以降)
今後はTimeオブジェクトからタイムゾーン情報も参照できるようになり、より正確な時間情報の扱いが可能になります。
action_dispatch.strict_freshness = true
2. 概要
HTTP ヘッダーの If-Modified-Since
と If-None-Match
に基づいてリソースが変更されたかどうかを判断する際の挙動を制御します。
設定オプション:
-
true
:
両方のヘッダーが存在する場合、If-None-Match
のみが考慮されます。 -
false
:
両方のヘッダーが存在する場合、両方のヘッダーがチェックされます。
Rails 8.0以降では、RFC 7232に準拠するように、デフォルト値がtrueに変更されました。
Regexp.timeout ||= 1
3. 概要
ReDoS 対策のため、 Regexp.timeout
にデフォルトで1秒をセットします。
正規表現に1秒以上かかる場合はタイムアウトエラーが発生するようになるので、必要に応じて設定値を変更する必要があります。
Regexp::TimeoutError: regexp match timeout
QA環境にデプロイして動作確認する
ローカル環境での確認とCIのテストにパスしたら、QA環境(テスト環境)で動作確認を行います。
マイベストでは月に一度、PdMによって定期点検を目的としたサービス全体の動作確認が実施されます。
今回は事前にPdMとコンタクトを取り、定期点検に相乗りして主要な機能を動作確認してもらいました。
本番環境にデプロイ
動作確認とコードレビューが完了したら、いよいよ本番環境にデプロイします!
問題をすぐに検知し、ユーザーやエンジニアへの影響を最小限にできるよう、全体に周知しておきます。
スタンプに背中を押され、いざデプロイ...!
無事、何の問題もなくアップグレードを完了できました。
まとめ
GemのChangelogを確認することが予想以上に地道で、アップグレード作業全体の半分の時間を充てることになりました。Dependabotを活用していなければさらに時間がかかっていたので、日頃からのアップデートの大切さを改めて感じました。
また、今回変更を加えた行数は、以下のようになりました。
Dependabotのおかげもあり、Gem関連の変更は最小限に抑えられました。
Pull Request | 変更行数 |
---|---|
Railsアップグレード | ![]() |
開発環境とテスト環境のgemアップデート | ![]() |
RSpecのリファクタリング | ![]() |
合計 | +571 −700 |
個人的に「作業漏れなく確実にアップグレードをやり切る」「絶対にサービスを止めない」というスタンスで臨んでいたため、やり遂げられてホッとしました。徹底して調査したことで、最後は確かな自信を持ってリリースできました。
調査にあたっては、この3点を意識すると網羅的に進めることができます。
- Gemの破壊的変更をリポジトリのChangelogで確認
- Rails アップデートタスクの差分をRails Diffで確認
- デフォルト設定の変更点をリリースノートで確認
Rails8.0は新機能の追加がメインであり、対応が必要な変更点は少なかったため、今後またアップグレードする機会があったら挑戦してみたいと思います。
参考資料

株式会社マイベストのテックブログです! 採用情報はこちら > notion.so/mybestcom/mybest-information-for-Engineers-8beadd9c91ef4dc2b21171d48a4b0c49
Discussion
すごく分かりやすかったです!👏
gemのバージョンアップによるメトリクスへの影響(メモリ使用量減少とか)も知りたくなりました!
ありがとうございます!

黒い縦線がリリースタイミングですが、今回はメトリクス上に大きな変化はなかったです。