ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

Rails 5 から Rails 6 へアップデートした際の手順

以前 Rails 4 を Rails 5 に上げる記事を書きましたが、
同様に Rails 5 から Rails 6 へ上げる作業をおこないましたので、詳細を書きます。

1. なぜ上げたかったか

Rails 5 に上げた記事にて『Ruby 2.6 にした場合に deprecation warning が出てしまったこと』をバージョンアップの理由に書きましたが、
Rails 6 に上げた理由も実は同様で、Ruby 2.7 にした場合に deprecation warning が出てしまうため でした。

/bundle/ruby/2.7.0/gems/activemodel-5.2.4.4/lib/active_model/translation.rb:67: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/bundle/ruby/2.7.0/gems/actionview-5.2.4.4/lib/action_view/helpers/form_helper.rb:755: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/bundle/ruby/2.7.0/gems/actionpack-5.2.4.4/lib/abstract_controller/helpers.rb:67: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call

上のように、Ruby 3 で廃止される予定のキーワード引数の記法について deprecated warning が出ます。
(詳しくは Ruby 2.7 のリリースノート をご覧ください)

これに対応する修正は Rails 5 ではおこなわれていなく、
Rails 6.0.3 にておこなわれています。(プルリク: https://github.com/rails/rails/pull/37935

というわけで Ruby 3 が来ることも見据えて、Rails 6 に上げておきたかったわけです。

2. 下準備

  • config/application.rbconfig.load_defaults を 5.2 にまで上げる
    Rails 5 に上げたときでは config.load_defaults が 5.0 だったので、そこから差分を見つつ慎重に上げていった)
  • その当時での最新の Rails 5.2.4.4 にアップデート
  • 各種 gem をできるだけ最新バージョンにアップデート

3. Rails 6 に上げた際の作業内容

3-1. bin/rails app:update

Gemfile 内の rails バージョンを 5.2.4.4 から 6.0.3.3 に書き換えたのち、

bundle update rails

その後、

bin/rails app:update

で config ディレクトリ内のファイルをいくつか更新しました。

3-2. utf8_enforcer_tag メソッドの上書きについて削除

config/initializers/disable_utf8_enforcer_tag.rb として以下のようなファイルを置いていたのですが、
config.load_defaults を 6.0 にしたあとは不要になったので削除しました。

# Internet Explorer 5 対応で utf8=✓ がクエリに付く問題の解消。Rails 6 では default_enforce_utf8 オプションが false (デフォルト)であれば不要になる 
module ActionView  
  module Helpers   
    module FormTagHelper   
      def utf8_enforcer_tag  
        "".html_safe  
      end   
    end 
  end   
end

3-3. Zeitwerk の挙動を考慮し Inflector の設定

こちらの記事がわかりやすいのですが、
Zeitwerk ではファイル名から名前が推測されます

例えば class DailyKPIclass MonthlyKPI などのクラス定義がある場合、
ファイル名が daily_kpi.rb だと Zeitwerk 的には「DailyKpi ってクラス名があるのかな?」って探すのだけれど見つからないのでエラーになります。

このエラーを避けるには、 config/initializers/inflections.rb に以下のように指定してあげる必要があります。

ActiveSupport::Inflector.inflections do |inflect|
  inflect.acronym "KPI"
end

「Kpi って記すところもあるんだよなぁ〜」って場合には、
config/initializers/zeitwerk.rb などの名前でファイルを作って、

Rails.autoloaders.each do |autoloader|
  autoloader.inflector.inflect(
    "daily_kpi" => "DailyKPI",
    "monthly_kpi" => "MonthlyKPI",
  )
end

と、必要なところだけ、ファイル名と名前の関係性を作るということも可能です。

3-4. redis-rails の使用をやめる

You're using a cache store that doesn't support native cache versioning.
Your best option is to upgrade to a newer version of ActiveSupport::Cache::RedisStore
that supports cache versioning (ActiveSupport::Cache::RedisStore.supports_cache_versioning? #=> true).

上記のエラーが出たので調べて、
Rails 5.2 から redis が Rails に内蔵されるようになっていたことを知ったので、
redis-rails の使用をやめて redis_cache_store を使うよう変更しました。

redis-rails の最後のリリースって、2017/04 なんですね……。
https://rubygems.org/gems/redis-rails/versions

redis-rails を Gemfile から取り除いて bundle install したのち、
以下のように config を変更しました。

# before
config.cache_store = :redis_store, ENV["REDIS_URL"], { expires_in: 1.hour }

# after
config.cache_store = :redis_cache_store, { url: ENV["REDIS_URL"], expires_in: 1.hour }

4. Rails 6 へのアップデートを終えて

Rails 5.2 から Rails 6.0 へのアップデートは、予想していた通り、
Rails 4 → Rails 5 へのアップデートよりもずいぶんとカンタンに終えられました。

Rails 6 へのアップデートを終えたことにより、
今後の Rails バージョンアップだけでなく Ruby のバージョンアップにも追従しやすくなりました。

Rails 5.2 をお使いの方は、ぜひ Railsガイドのアップグレードガイド を読みつつ、
Rails 6.0 へのアップデートをおこなってみてください。
Zeitwerk の挙動と、cookie 情報の後方互換性のない変更あたりに気を付ければ、だいたい大丈夫かと思います。