🦓

[Rails]rails6から7へのバージョンアップ

2023/07/18に公開

はじめに

Rails 6.1.7.3
ruby 3.0.0
で作ったアプリをアップグレードしていきます。

アップグレード後の環境はこちらとなります:
Rails 7.0.4
ruby 3.2.2

ドキュメントを参考しながらやっていきましょう。
https://railsguides.jp/upgrading_ruby_on_rails.html

RubyのアップグレードとRailsのアップグレードは別々に行うのがよい方法です。最初にRubyを可能な限り最新版にアップグレードし、それからRailsをアップグレードします。

Rubyをアップグレードする

いま使っているバージョンです。

ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin22]

.ruby-versionを編集する

.ruby-version
- 3.0.0
+ 3.2.2

Gemfileを編集する

Gemfile
- ruby '3.0.0'
+ ruby '~> 3.2'

'~> 3.2'はRubyのバージョン指定の一形式で、セマンティック バージョニング(Semantic Versioning)と呼ばれる規則に基づいています。この指定は一般的に、依存関係管理システムで使用されます。

セマンティック バージョニングでは、バージョン番号はMAJOR.MINOR.PATCHの形式で表されます。MAJORは主要な変更が行われるときに増加し、MINORは後方互換性がある機能追加が行われるときに増加し、PATCHはバグ修正などの後方互換性のある修正が行われるときに増加します。

'~> 3.2'は、MAJORが3であることと、MINORが2以上であり、かつ3未満であることを指定しています。つまり、3.2.x(3.2.0、3.2.1、3.2.2など)のバージョンを指定しています。一方で、3.3.0以上のバージョンは含まれません。

この指定は、依存関係を持つGemやライブラリが、特定のバージョン範囲内で動作することを示すために使用されます。例えば、gem 'rails', '~> 6.0'は、Railsのバージョンを6.0.x(6.0.0、6.0.1、6.0.2など)に制約することを意味します。

このような指定は、プロジェクトの互換性と安定性を保つために役立ちます。新しいパッチリリースが行われた場合でも、自動的にそれにアップグレードすることができますが、一方で互換性のない新しいバージョンがリリースされた場合には、明示的な変更が必要になります。

rubyをインストールする

rubyのバージョンマネージャーのrbenvを使っていますので3.2.2をインストールします。

rbenv install -l
3.0.6
3.1.4
3.2.2
jruby-9.4.2.0
mruby-3.2.0
picoruby-3.0.0
truffleruby-22.3.1
truffleruby+graalvm-22.3.1

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all / -L' to show all local versions.

# インストール
rbenv install 3.2.2
...
Downloading ruby-3.2.2.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz
Installing ruby-3.2.2...
ruby-build: using readline from homebrew
ruby-build: using libyaml from homebrew
Installed ruby-3.2.2 to /Users/chloe/.rbenv/versions/3.2.2

➜ rbenv local 3.2.2
➜ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-darwin22]

RubyGemsをアップデートする

RubyGems(ルビージェムズ)は、Rubyの公式のパッケージ管理システムです。RubyGemsを使用することで、Rubyのライブラリやアプリケーションを簡単にダウンロード、インストール、管理することができます。

Rubyのアップグレードが行われた場合、それに伴ってRubyGemsのバージョンも更新する必要があります。新しいRubyバージョンと互換性のあるRubyGemsを使用するために、gem update --systemコマンドを実行します。

gem update --system
Updating rubygems-update
Fetching rubygems-update-3.4.17.gem
Successfully installed rubygems-update-3.4.17
Parsing documentation for rubygems-update-3.4.17
Installing ri documentation for rubygems-update-3.4.17
Done installing documentation for rubygems-update after 43 seconds
Parsing documentation for rubygems-update-3.4.17
Done installing documentation for rubygems-update after 0 seconds
Installing RubyGems 3.4.17
  Successfully built RubyGem
  Name: bundler
  Version: 2.4.17
  File: bundler-2.4.17.gem
Bundler 2.4.17 installed
RubyGems 3.4.17 installed
Regenerating binstubs
Regenerating plugins
Parsing documentation for rubygems-3.4.17
Installing ri documentation for rubygems-3.4.17

# 3.4.17 / 2023-07-14

## Enhancements:

* Installs bundler 2.4.17 as a default gem.

## Performance:

* Avoid unnecessary work for private local gem installation. Pull request
  [#6810](https://github.com/rubygems/rubygems/pull/6810) by
  deivid-rodriguez

# 3.4.16 / 2023-07-10

## Enhancements:

* Installs bundler 2.4.16 as a default gem.

# 3.4.15 / 2023-06-29

## Enhancements:

* Installs bundler 2.4.15 as a default gem.

## Bug fixes:

* Autoload shellwords when it's needed. Pull request
  [#6734](https://github.com/rubygems/rubygems/pull/6734) by ioquatix

## Documentation:

* Update command to test local gem command changes. Pull request
  [#6761](https://github.com/rubygems/rubygems/pull/6761) by jenshenny

# 3.4.14 / 2023-06-12

## Enhancements:

* Load plugin immediately. Pull request
  [#6673](https://github.com/rubygems/rubygems/pull/6673) by kou
* Installs bundler 2.4.14 as a default gem.

## Documentation:

* Clarify what the `rubygems-update` gem is for, and link to source code
  and guides. Pull request
  [#6710](https://github.com/rubygems/rubygems/pull/6710) by davetron5000

# 3.4.13 / 2023-05-09

## Enhancements:

* Installs bundler 2.4.13 as a default gem.

# 3.4.12 / 2023-04-11

## Enhancements:

* [Experimental] Add WebAuthn Support to the CLI. Pull request
  [#6560](https://github.com/rubygems/rubygems/pull/6560) by jenshenny
* Installs bundler 2.4.12 as a default gem.

# 3.4.11 / 2023-04-10

## Enhancements:

* Installs bundler 2.4.11 as a default gem.


------------------------------------------------------------------------------

RubyGems installed the following executables:
        /Users/***/.rbenv/versions/3.2.2/bin/gem
        /Users/***/.rbenv/versions/3.2.2/bin/bundle
        /Users/***/.rbenv/versions/3.2.2/bin/bundler

Ruby Interactive (ri) documentation was installed. ri is kind of like man 
pages for Ruby libraries. You may access it like this:
  ri Classname
  ri Classname.class_method
  ri Classname#instance_method
If you do not wish to install this documentation in the future, use the
--no-document flag, or set it as the default in your ~/.gemrc file. See
'gem help env' for details.

RubyGems system software updated

gemをアップデートする

すべての場合においてGemバージョンを明示的に指定する必要があるわけではありません。特定のGemに関しては、柔軟性を持たせるためにバージョン範囲を指定することもできます。rubyのような~> 3.2の範囲指定や、>= 1.0, < 2.0のような条件指定ができます。バージョン範囲や条件指定を使用することで、特定の範囲内で最新の互換性のあるバージョンを自動的に利用することができます。

Rubyのバージョンアップに伴い、既存のGemが互換性のない変更に対応していない場合、正常に動作しない可能性があります。そのため、新しいバージョンのRubyに合わせてGemをアップデートする必要があります。

bundle install
...
Bundle complete! 34 Gemfile dependencies, 124 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

rubyのバージョンアップが完了しました。

Railsをアップグレードする

ドキュメントに記載されている手順に沿ってrailsのバージョンも上げていきます。
テストがないため今回は飛ばします。

  1. Gemfileファイル内のRailsバージョン番号を変更し、bundle updateを実行する。
  2. package.jsonファイル内のRails JavaScriptパッケージのバージョンを変更する。Webpackerで動かす場合はyarn installを実行する。
  3. アップデートタスクを実行する。
  4. テストを実行する。

Gemfileを編集する

.ruby-version
- gem 'rails', '~> 6.1.7', '>= 6.1.7.3'
+ gem 'rails', '~> 7.0', '>= 7.0.4.3'
bundle update
...
Fetching rails 7.0.6 (was 6.1.7.3)
Installing rails 7.0.6 (was 6.1.7.3)
Bundle updated!

https://rubygems.org/gems/rails/versions/7.0.4.3

package.jsonを編集する

package.json
{
  "dependencies": {
- "@rails/actioncable": "^6.0.0",
- "@rails/activestorage": "^6.0.0",
- "@rails/ujs": "^6.0.0",

+ "@rails/actioncable": "^7.0.4-3",
+ "@rails/activestorage": "^7.0.5-1",
+ "@rails/ujs": "^7.0.5-1",
  },
}

npmの公式ページのパッケージのバージョンを参考にしてバージョンを指定します。
https://www.npmjs.com/package/@rails/ujs?activeTab=versions

yarn install
yarn install v1.22.19
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning "@babel/plugin-proposal-private-methods > @babel/helper-create-class-features-plugin@7.22.5" has unmet peer dependency "@babel/core@^7.0.0".
warning "@babel/plugin-proposal-private-property-in-object > @babel/plugin-syntax-private-property-in-object@7.14.5" has unmet peer dependency "@babel/core@^7.0.0-0".
warning " > @babel/plugin-proposal-private-methods@7.18.6" has unmet peer dependency "@babel/core@^7.0.0-0".
warning " > @babel/plugin-proposal-private-property-in-object@7.21.11" has unmet peer dependency "@babel/core@^7.0.0-0".
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 5.75s.

アップデートタスク

bin/rails app:updateは、Railsアプリケーションをアップデートするためのコマンドです。このコマンドを使用すると、古いバージョンのRailsアプリケーションを新しいバージョンにアップデートするための手順が実行されます。

bin/rails app:updateコマンドを実行すると、以下のような手順が実行されます。

  1. アプリケーションのバージョンアップに関連する変更を適用します。これには、新しいバージョンのRailsに関連する設定やファイルの変更が含まれます。
  2. コンフリクトの解決: 既存のアプリケーションにカスタマイズや変更がある場合、app:updateコマンド実行時にコンフリクトが発生する可能性があります。この場合、コマンドはコンフリクトを検出し、対話的に解決するように求めます。
  3. 設定ファイルのマージ: app:updateコマンドは、アプリケーションの新しいバージョンに関連する設定ファイルを現在の設定ファイルとマージします。これにより、既存の設定を維持しながら新しいバージョンに関連する設定を反映できます。

bin/rails app:updateコマンドは、Railsのバージョンアップに関連する手順を自動化し、既存のアプリケーションを新しいバージョンに適合させるのに役立ちます。ただし、コマンドを実行する前に、プロジェクトのバックアップやテストを行い、変更がアプリケーションに影響を及ぼさないことを確認することをおすすめします。また、アプリケーションのバージョンアップに伴って非推奨の機能や仕様がある場合、それらの変更に適応する必要があるかもしれません。

bin/rails app:update
➜  rails_review git:(rails_upgrade) ✗ bin/rails app:update
    conflict  config/boot.rb
       force  config/boot.rb
    conflict  config/application.rb
       force  config/application.rb
   identical  config/environment.rb
       exist  config/environments
    conflict  config/environments/development.rb
       force  config/environments/development.rb
    conflict  config/environments/production.rb
       force  config/environments/production.rb
    conflict  config/environments/test.rb
       force  config/environments/test.rb
       exist  config/initializers
    conflict  config/initializers/assets.rb
       force  config/initializers/assets.rb
    conflict  config/initializers/content_security_policy.rb
       force  config/initializers/content_security_policy.rb
      create  config/initializers/cors.rb
    conflict  config/initializers/filter_parameter_logging.rb
       force  config/initializers/filter_parameter_logging.rb
    conflict  config/initializers/inflections.rb
       force  config/initializers/inflections.rb
      create  config/initializers/new_framework_defaults_7_0.rb
   identical  config/initializers/permissions_policy.rb
      remove  config/initializers/cors.rb
File unchanged! Either the supplied flag value not found or the content has already been inserted!  config/application.rb
       exist  bin
    conflict  bin/rails
       force  bin/rails
    conflict  bin/rake
       force  bin/rake
    conflict  bin/setup
       force  bin/setup
        gsub  db/schema.rb
       rails  active_storage:update

Copied migration 20230718143112_add_service_name_to_active_storage_blobs.active_storage.rb from active_storage
Copied migration 20230718143113_create_active_storage_variant_records.active_storage.rb from active_storage
Copied migration 20230718143114_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb from active_storage

After this, check Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html for more details about upgrading your app.

DBをマイグレーションする

bin/rails db:migrate RAILS_ENV=development
== 20230718143112 AddServiceNameToActiveStorageBlobs: migrating ===============
-- table_exists?(:active_storage_blobs)
   -> 0.0010s
== 20230718143112 AddServiceNameToActiveStorageBlobs: migrated (0.0010s) ======

== 20230718143113 CreateActiveStorageVariantRecords: migrating ================
-- table_exists?(:active_storage_blobs)
   -> 0.0011s
== 20230718143113 CreateActiveStorageVariantRecords: migrated (0.0012s) =======

== 20230718143114 RemoveNotNullOnActiveStorageBlobsChecksum: migrating ========
-- table_exists?(:active_storage_blobs)
   -> 0.0007s
== 20230718143114 RemoveNotNullOnActiveStorageBlobsChecksum: migrated (0.0007s) 

マイグレーション後サーバーを立ち上げてアプリの動きを確認します。
ログにあるRailsとrubyのバージョンがアップグレードされましたね。

bin/rails s
=> Booting Puma
=> Rails 7.0.6 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.6 (ruby 3.2.2-p53) ("Birdie's Version")
...

Turboの機能を使う

method: :deleteturbo_method: deleteにしてみましたがGETリクエストを送られ削除することができませんでした。
turboが効かないため@hotwired/turbo-railsをインストールします。

Hotwire Turboは、Railsアプリケーションで使用されるJavaScriptフレームワークであり、クライアントサイドでのパフォーマンスの向上とリアルタイムな更新を実現します。
@hotwired/turbo-railsはTurboの公式パッケージであり、Turboの機能を使用するために必要なヘルパーやモジュールを提供します。

Rails 6以降のバージョンで追加された新しいフレームワークですが、Rails 6ではturbolinksが使われていたため手動でインストールする必要があります。

Gemfileにあるturbolinksを削除します。

Gemfile
- gem 'turbolinks', '~> 5'
bundle install
yarn add @hotwired/turbo-rails
...
info Direct dependencies
├─ @hotwired/turbo-rails@7.3.0
└─ @rails/ujs@7.0.6
info All dependencies
├─ @hotwired/turbo-rails@7.3.0
├─ @hotwired/turbo@7.3.0
└─ @rails/ujs@7.0.6
✨  Done in 6.59s.

application.jsにインポートします。

app/javascript/packs/application.js
import { Turbo } from "@hotwired/turbo-rails"

turboを使えるようになりました。

https://www.npmjs.com/package/@hotwired/turbo-rails

差分を確認する

gitの差分を確認します。

RailsDiffで設定ファイルの更新を確認します。
バージョンごとの設定ファイルの差分を閲覧出来るRailsDiffというサービスを使って差分を確認しつつ、反映が必要そうな箇所を修正していきます。

https://railsdiff.org/6.1.7.4/7.0.6

終わり

無事にrubyとrailsをアップグレードすることができました。

Discussion