AetherEchoesEngineering
Vol.042026年5月9日
Engineering#00551 min5309 view

Rails 6.1 → 8.1 のメジャー移行で踏んだ 7 つの罠

load_defaults / Spring / show_exceptions / unprocessable_content。AetherEchoes バックエンドを 6.1 から 8.1 に上げた実録。

SoSoraEndo2026年5月9日1 min530

何が変わったか

Rails 8.1 への移行で実質的に手当が必要だったのは、load_defaults が 8.1 になったことによる挙動変更と、Spring の同梱廃止、unprocessable_entity の rename、config.action_dispatch.show_exceptions のシンボル化、の 4 つだった。

API-only 構成(--api)でも引っかかる箇所はある。順に書いておく。

load_defaults 8.1

最初の罠。Rails 8.1 で load_defaults をそのまま 8.1 に上げると、新規 framework デフォルトがいくつか有効化される。

# config/application.rb
config.load_defaults 8.1

その上で 以前の挙動を残したい設定だけを new_framework_defaults_8_1.rb で個別に false に戻す のが正解。一気に上げて全部新挙動に乗せると、テストの落ち方の見当がつかなくなる。

私の場合は config.action_dispatch.default_headers の更新と、config.action_controller.allow_deprecated_parameters_hash_equality あたりが効いた。

Spring 廃止

Rails 8 で Spring が同梱から外れた。bin/railsbin/rake の頭の Spring.binstub を削るか、bin/railsbundle exec rails 直叩きに切り替えるかどちらか。

私は Spring を消す 側を選んだ。Docker 内で動かす前提だと、Spring の preloader はメリットが薄い。bin/spring を削除し、Gemfile から spring-watcher-listen を抜いた。

show_exceptions のシンボル化

config.action_dispatch.show_exceptions = false だったのが、= :none / :rescuable / :all の 3 値シンボルに変わった。false のままだと dev で ActionView::ActionRescuable が動かない。

# 旧:
config.action_dispatch.show_exceptions = false

# 新:
config.action_dispatch.show_exceptions = :rescuable  # = 旧 false 相当

:none だと例外が一切 rescue されないため、開発中に困る。:rescuable が現実的。

unprocessable_entity → unprocessable_content

HTTP 422 のシンボルが :unprocessable_entity から :unprocessable_content に rename された。互換 alias は残っているので慌てる必要はない が、新コードは :unprocessable_content で書くのが正解。

私は controller を全文 grep で書き換えた:

grep -rln 'unprocessable_entity' app/controllers/ | xargs sed -i '' 's/unprocessable_entity/unprocessable_content/g'

まとめ

API-only な Rails アプリの場合、Rails 8.1 の移行コストは 半日 で終わる。Web アプリ(views ありの monolith)はもっと時間がかかると思う。

移行は「どうせいつかやる」を後回しにしないのが近道。半年放置するごとに罠が増える。

Tags

Reaction

Share

X (Twitter)