Rails7.0にアプリケーションをアップデートしています


原田です。今回は弊社内で開発中のRuby on Rails(以下、Rails)アプリケーションをVer6.1系からVer7.0系にアップデートした手順の一部をご紹介します。

開発中のRailsアプリケーションについて


開発中のRailsアプリケーション

通常のRailsアプリケーションはデータベース(テーブル)上のデータに対して作成(Create)・読み出し(Read)・更新(Update)・削除(Delete)を実施しますが、開発中のアプリケーションではデータベースは使用しておらずテキストファイルに対して読み書き(Read/Write)を行います。データベースであれば一連のSQLをトランザクションで管理しデータの一貫性を保つことができますが、テキストファイルの場合は書き込み処理でテキストファイルを一時的にロックすることでデータの一貫性を保つようにしています。

書き込み処理の一例

def save!
  File.open('sample.conf', 'w') do |f|
    f.flock(File::LOCK_EX)
    self.config.write(f, false)
    f.flock(File::LOCK_UN)
  end
end

アプリケーションのアップデート

今回のアップデートでは大きく以下の作業を実施しました。

これらの作業の動作確認は(設定等に誤りがあっても容易に作り直せるので)Dockerコンテナで実施しています。最終的にはAmazon ECSを使用してコンテナで運用することを考えております。

Ruby2.7から3.1にアップデート

上記のとおりDocker(Dockerfile)を使用していますので、以下のような変更で簡単(手軽)にRubyをアップデートすることができます。(以前にオンプレミス環境でRuby1系から2系にアップデートを実施した時は大変苦労しました)

diff --git a/Dockerfile b/Dockerfile
index dc318be..6f7a181 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM ruby:2.7.0-slim
+FROM ruby:3.1.2-slim
 MAINTAINER harada <harada@example.com>

 ENV DEBIAN_FRONTEND=noninteractive

Rails6.1から7.0にアップデート

Railsのアップデートは過去何度か実施しておりますが、アプリケーションの構成等を考慮する必要があるためRubyとは異なりRailsのアップデートは複雑になると思われます。開発中のアプリケーションはActiveRecordやActiveStorageを使用していないので、その分アップデートは楽なのかもしれません。

大まかではありますが以下の手順でRailsのアップデートを実施(注:Dockerコンテナ内で実施)しました。

※ 実際には未使用機能(ActiveJob, ActionCableなど)の見直し(削除)等も実施しております。(説明は省略します)

手順1: Gemfile上のrailsを7系に変更し、bundle updateを実施します。

diff --git a/Gemfile b/Gemfile
index 3b2ad20..161393c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,13 +1,13 @@
 source "https://rubygems.org"
 git_source(:github) { |repo| "https://github.com/#{repo}.git" }

-ruby "2.7.0"
-gem "bundler", "2.1.4"
+ruby "3.1.2"
+gem "bundler", "2.3.16"

 # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
-gem "rails", "~> 6.1.3", ">= 6.1.3.1"
+gem "rails", "7.0.3"
 # Use i18n default language set
-gem "rails-i18n", "~> 6.0"
+gem "rails-i18n", "~> 7.0.0"

 # Use the Puma web server [https://github.com/puma/puma]
 gem "puma", "~> 5.0"

手順2: bin/rails app:updateを実施すると、configディレクトリ下の設定ファイル等の変更を提案してきますので適宜更新してください。

bin/rails app:update の実行例(クリックで表示します)
root@c2c53e31ad47:/var/lib/sample_app# bin/rails app:update

    conflict  config/boot.rb
Overwrite ./config/boot.rb? (enter "h" for help) [Ynaqdhm]
       force  config/boot.rb
       exist  config
    conflict  config/application.rb
Overwrite ./config/application.rb? (enter "h" for help) [Ynaqdhm]
       force  config/application.rb
    conflict  config/environment.rb
Overwrite ./config/environment.rb? (enter "h" for help) [Ynaqdhm]
       force  config/environment.rb
       exist  config/environments
    conflict  config/environments/development.rb
Overwrite ./config/environments/development.rb? (enter "h" for help) [Ynaqdhm]
       force  config/environments/development.rb
    conflict  config/environments/production.rb
Overwrite ./config/environments/production.rb? (enter "h" for help) [Ynaqdhm]
       force  config/environments/production.rb
    conflict  config/environments/test.rb
Overwrite ./config/environments/test.rb? (enter "h" for help) [Ynaqdhm]
       force  config/environments/test.rb
       exist  config/initializers
    conflict  config/initializers/assets.rb
Overwrite ./config/initializers/assets.rb? (enter "h" for help) [Ynaqdhm]
       force  config/initializers/assets.rb
    conflict  config/initializers/content_security_policy.rb
Overwrite ./config/initializers/content_security_policy.rb? (enter "h" for help) [Ynaqdhm]
       force  config/initializers/content_security_policy.rb
      create  config/initializers/cors.rb
    conflict  config/initializers/filter_parameter_logging.rb
Overwrite ./config/initializers/filter_parameter_logging.rb? (enter "h" for help) [Ynaqdhm]
       force  config/initializers/filter_parameter_logging.rb
    conflict  config/initializers/inflections.rb
Overwrite ./config/initializers/inflections.rb? (enter "h" for help) [Ynaqdhm]
       force  config/initializers/inflections.rb
      create  config/initializers/new_framework_defaults_7_0.rb
    conflict  config/initializers/permissions_policy.rb
Overwrite ./config/initializers/permissions_policy.rb? (enter "h" for help) [Ynaqdhm]
       force  config/initializers/permissions_policy.rb
      remove  config/initializers/cors.rb
File unchanged! The supplied flag value not found!  config/application.rb
       exist  bin
    conflict  bin/rails
Overwrite ./bin/rails? (enter "h" for help) [Ynaqdhm]
       force  bin/rails
    conflict  bin/rake
Overwrite ./bin/rake? (enter "h" for help) [Ynaqdhm]
       force  bin/rake
    conflict  bin/setup
Overwrite ./bin/setup? (enter "h" for help) [Ynaqdhm]
       force  bin/setup

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


手順3: bin/rails app:updateを実施しRails6.1系から7.0系にアップデートするとconfig/initializers/new_framework_defaults_7_0.rbが生成されます。このファイルにはRails7.0で動作するためのデフォルト値が19項目定義されており全てコメントアウトされています。1項目ずつコメントを外し動作確認をし、全ての項目で問題がなければnew_framework_defaults_7_0.rbを削除し、config/application.rbに記載のconfig.load_defaults 6.1config.load_defaults 7.0に変更する手順になります。(弊社の場合ActiveRecord等を使用していないので該当項目の動作確認は未実施です)

diff --git a/config/application.rb b/config/application.rb
index eda93a5..15df6b3 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -24,7 +24,7 @@ Bundler.require(*Rails.groups)
 module SampleApp
   class Application < Rails::Application
     # Initialize configuration defaults for originally generated Rails version.
-    config.load_defaults 6.1
+    config.load_defaults 7.0
     config.eager_load_paths << "#{root}/lib"
     config.i18n.available_locales = %i[ja en]
     config.i18n.default_locale = :ja

なお19項目の詳細につきましては、rails7へのバージョンアップを安全に行うために使用するnew_framework_defaults_7_0.rbの各項目をさらっと解説 - Qiitaが大変参考になりました。

手順4: Upgrading Ruby on Rails — Ruby on Rails GuidesRails アップグレードガイド - Railsガイドを確認し、必要に応じて見直し・調整等を実施してください。

先人の知恵を活用することも大切です

今回のRailsアップデートですけど当初私自身の力のみで完了させようと試みましたが、新たな技術や手法など様々なものが出てきておりこれまでに学習し記憶に定着している内容だけでは対応できないことが多くありました。これらを解決するためにインターネット上に公開されている様々な情報が大変助けになりました。

現在開発中のRailsアプリケーションではWebpackerを用いてJavaScriptやCSSなどを取り込んでいますが、これをRails7.0推奨のImportmapで実現しようと検証しています。これも世界中の方々がすでに実施されており、いくつか参考になる情報を確認しております。このような皆さんのためになる情報を私も発信できるようになれればいいなと思いました。

My Redmine

こちらの記事もオススメです!
Redmine 5.0で古いプラグインを動作させる方法(Zeitwerk対応)
Redmine 5.0ではZeitwerkが採用され、プラグインがZeitwerkに対応していないとRedmine 5.0は起動しません。
AWS マネジメントコンソールへのログイン通知(2022年版)
証跡をマルチリージョン対応し他のサービスを連携して比較的簡単に対応ができました。
Redmineに関するオンラインセミナーを始めて1年経ったふりかえり
セミナーの開催にあたり準備したことや良かったことをふりかえります。
中国の小中高生向けオンライン教育プラットフォーム「国家中小学智慧教育平台」がすごい
「国家中小学智慧教育平台」は教科書のPDFが無料でダウンロードでき、また多くの科目の講義動画を見ることができます。
ファーエンドテクノロジーに入社しました
2022年4月に入社しました。開発やマーケティングの支援を行なっています。
ファーエンドテクノロジーからのお知らせ(2022/06/15更新)
RedMica 2.1 バージョンアップのお知らせ
My Redmineで提供しているソフトウェアをRedMica(ファーエンドテクノロジー版Redmine) 2.0 から 2.1 へバージョンアップいたします。
プロジェクト管理ツール「RedMica」バージョン 2.1.0をリリース Redmine互換のオープンソースソフトウェア
今日使える明日のRedmine「RedMica」の最新バージョン2.1.0をリリースしました。次期バージョン Redmine 5.1の新機能を先行利用できます。
月例Redmineセミナー「Redmine利用事例紹介 株式会社イシダテック様」【2022/7/7開催】
「Redmineでゼロから始めたプロジェクト管理〜製造業でRedmineを使いこなすための勘所〜」株式会社イシダテック様。Redmineをどのように業務で活用しているのか企業様の事例をご紹介します。
APPS JAPAN 2022(6/15〜17開催) にRedmineのブースを出展
6月15日〜17日に幕張メッセで開催される「APPS JAPAN 2022」にプロジェクト管理のオープンソース「Redmine」と「RedMica」、Redmineのクラウド版「My Redmine」などを紹介するブースを出展します。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け