🛤️

Rails7.0アップグレード手順とハマりどころのTips

2022/04/19に公開2

株式会社KINECAでエンタメマッチングサービスを開発しているryosk7です。
今回Rails6.1から7.0にアップグレードした際にいろいろハマったので、シェアしていこうと思います。
執筆時点(2022/4/19)では、あまりドキュメントも揃っていない状態なので、今後アップグレードする方々の参考になればと思います。

アップグレード手順

アップグレード手順から先に話しますが、ハマってどうしようもない人は後述するハマりポイントを見ながら進めるといいかもしれません。

アップグレードタスクを実行

Railsガイド アップグレードガイド

gemのバージョンを変更し、

Gemfile
gem 'rails', '7.0.2.3'

以下コマンドを叩いて、アップグレードタスクを実行します。

zsh
$ bin/rails app:update

基本的に上書き更新して進めていきます。(routesは上書きするとかなり消えてしまうのでここだけ飛ばします)
アップグレードタスクで行う内容は過去バージョンのアップグレード対応と基本は同じなので、以下の記事が参考になると思います。
https://qiita.com/jnchito/items/0ee47108972a0e302caf

warningが発生するので、潰していきます。

to_s 👉 to_fsに変更

Ruby 3.1でto_sにパフォーマンスチューニングがされましたが、Railsはto_sを一連のクラスに適用しており、Rubyの変更による恩恵を受けられない状態でした。

https://github.com/rails/rails/pull/43772

この最適化を将来的に利用するために、Railsは従来のto_sオーバーライドを廃止し、to_formatted_sを使用することを推奨しています。
aliasとしてto_fsというのも用意されているので、こちらを利用しました。

gem "sprockets-rails"を追加

gem "sprockets-rails"がオプションになったので、Rails6.1時点で利用している場合は追加します。

Gemfile
+ gem "sprockets-rails"

zeitwerkモードでの実行が必須に

Rails6.1でclassicモードを利用している場合は変更が必要です。
幸いにも弊社サービスでは対応済みでした。
Rails6.1でもzeitwerkモードにできるので、アップグレード対応とは分けてリリースすることをお勧めします。
詳しい手順はこちら

残り作業

ローカル環境、Staging環境で動作確認をし、本番環境へリリースして作業修了です。

ハマりポイント

将来的には修正される可能性もありますが、執筆時点(2022/4/19)でハマってしまった部分を紹介します。

arproxyの利用でArgumentErrorが発生

https://github.com/cookpad/arproxy/pull/21#issuecomment-1014267087

このエラーは

#executeメソッドには、特にactiverecord 7.0.0以降のMySQLアダプターで、keyword-argumentsが含まれる場合があります

と、あるようにexecuteメソッドの引数部分を修正する必要があります。

multiple_database_connection_logger.rb
 class MultipleDatabaseConnectionLogger < Arproxy::Base
-  def execute(sql, name = nil)
+  def execute(sql, name = nil, **)

上記変更でこの問題は解決しました。

attr-encryptedの名前衝突によるエラー

ActiveRecord7から暗号化属性が追加されました。
弊社のサービスでは以前から一部カラムを暗号化させており、暗号化の際にattr-encryptedを使っていました。
https://github.com/attr-encrypted/attr_encrypted

attr_encrypted gemはメンテナンスがされておらず、ActiveRecord7の暗号化機能と多くの名前の衝突が発生します。
幸いにも、attr-encryptedをフォークし解決してくれたgemが存在したので、一時的に使う判断をしました。(タイミングを見てActirveRecordの暗号化に移行します。)
https://github.com/PagerTree/attr_encrypted/tree/rails-7-0-support

Gemfile
- gem "attr_encrypted"
+ gem "attr_encrypted", github: "PagerTree/attr_encrypted", branch: "rails-7-0-support"

Dockerfileを利用している方は、以下の変更も必要です。

Dockerfile
+ RUN apt install -y git

RUN bundle install

これで正常に動作します。

Missing templateエラー

jbuilderを使っている方に発生する事象です。
これ自体、これといった原因がわかっていないですが、formatを指定していたためエラーが発生していました。(わかる方がいたら教えてください🙇‍♂️)
似たような事象がいくつかのRailsバージョンで起こっているようです。
https://github.com/rails/jbuilder/issues/134

- render 'index', formats: :json, handlers: 'jbuilder'
+ render 'index'

上記変更により解決しました。

おわりに

attr-encryptedの解決が一番時間かかりました。
ざざーっと説明しましたが、大体こんな感じで進めていけばRails7.0を本番運用できると思います。
Rails7.0からフロントエンド周りの機構が刷新されたので、試してみようと思います。

Discussion

nognog

こちらと完全に同一の問題かはわからないですが、Rails7への更新でMissing Templateエラーの問題に自分も引っかかりました。
Railsの該当ソースまで追い切れていないのですが、handlersに渡すのがStringだとRails6系では動いていたものがRails7系では動かなくなったようです。
handlersへStringで渡していたところをSymbolに変更したところ動作するようになりました。