🦥

Rails6.1->7.0にアップグレードした話

2023/08/10に公開

はじめに

株式会社ウェイブCoolmicのエンジニアをしているあーもんどです。
Coolmicは、海外向けに日本のコミックを配信するWEBサービスとなります。

バックエンドをRails、フロントエンドをVueで実装しており、
今回は遅ればせながらRailsのバージョンを6.1から7.0.5にアップグレードした際の話をさせて頂きます。
既に参考になる記事はたくさんありますが、この記事がどなたかのお役に立てれば幸いです。

アップグレード手順

進め方は以下のような手順になります。

  1. アップグレードタスクを実行
  2. アップグレードへの対応
  3. new_framework_defaults_7_0.rbへの対応

それでは始めていきます!

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

  1. gemのrailsのバージョンを書き換える
Gemfile
gem 'rails', '7.0.5'
  1. bundle update railsを実行
    ここで、Rails7.0に対応していないgemがある場合は指摘されるので、解決後、再実行します。

  2. rails app:updateを実行
    このタスクを実行すると、新しいバージョンにて新たに必要になるファイルや、変更が発生してコンフリクトが生じるファイルが出てきます。
    それらを対話形式で解決していきます。
    基本的にコンフリクトしたファイルに対してdで差分を確認し、Ynを入力する作業になるかと思います。

2. アップグレードへの対応

Zeitwerkモードでの起動が必須

ファイルの自動ロードのモードとして、classicモードが廃止され、zeitwerkモードの起動が必須になりました。
これにより大きな影響があるわけではないと思いますが、私達のコードには少し影響がありました。
以下のようなファイル名とクラス名の関係は、classicモードでは問題なかったのですが、zeitwerkモードではロードに失敗してしまいます。

  • ファイル名:signup.rb
  • クラス名:SignUp

この場合、ファイル名をsign_upにするか、クラス名をSignupに修正しなくてはいけません。

to_sではなくto_fsを推奨

従来のto_sオーバーライドが廃止され、to_formatted_sを使用することが推奨されます。
エイリアスとしてto_fsが用意されております。

3. new_framework_defaults_7_0.rbへの対応

コメントアウトを外していきながらテストが通るか、などの確認をします。
全て問題なかったら以下のように更新します。

application.rb
config.load_defaults=7.0

対応が必要になった項目

config.action_controller.raise_on_open_redirects

OAuth 2.0の認可などで外部ページにリダイレクトさせることがあると思いますが、オープンリダイレクト攻撃を防ぐために、外部ページへのリダイレクトはデフォルトで無効になります。
一部のページに限って有効にするには、allow_other_host: trueをオプションとして追加します。

redirect_to hogehoge, allow_other_host: true

慎重になった項目

config.active_support.cache_format_version

説明が怖かったので慎重に、恐る恐る反映しました😱

new_framework_defaults_7_0.rb
# Only change this value after your application is fully deployed to Rails 7.0
# and you have no plans to rollback.

Rails7.0で使用したいメソッド

無事Rails7.0へアップグレードしたので、そのご利益を授かりたいと思います!
様々な機能やメソッドが追加されていますが、とりあえず使えそうと思ったメソッド2つを挙げます。

in_order_of

特定の値のセットによる順序の指定ができます。

User.in_order_of(:id, [1, 5, 3])
# postgresqlの場合
# SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 5, 3) ORDER BY CASE "users"."id" WHEN 1 THEN 1 WHEN 5 THEN 2 WHEN 3 THEN 3 ELSE 4 END ASC

associated

これは6.1で追加されたmissingの逆であり、関連先の存在するレコードのみを取得できます。

before
class Account < ApplicationRecord
  has_many :users, -> { joins(:contact).where.not(contact_id: nil) }
end
after
class Account < ApplicationRecord
  has_many :users, -> { where.associated(:contact) }
end

最後に

今回のアップグレード作業ですが、思ったより短期間で実施できたのはテストの充実度によるところが大きいと思います。
今まで開発に関わったメンバーがしっかりテストを書いてきたからであり、非常に感謝します。
今後は感謝の気持ちを忘れずに、新しいバージョンがリリースされたらすぐにアップグレードしていけるよう精進します!

宣伝

株式会社ウェイブでは、電子コミックやアニメ配信サービスなどを自社開発で運営しております。
一緒に働くメンバーを募集中ですので、ご興味ある方はぜひご覧ください!
https://recruit.wwwave.jp/

参考文献

wwwave's Techblog

Discussion