Ruby on Rails 6.xから7.0.xへアップグレード [エラー解決/移行ガイド]
今回は新規にプロジェクト(Ruby on Rails7.0.x)を作成して、そこに元のソースファイルを徐々に移動していきます。公式の移行ツールはありませんので手動で作業を行います。
前提条件
Ruby3.0以降 |
関連記事:Ruby/Ruby on Railsのアップグレード
1. プロジェクトの作成
rails new . --skip-turbolinks --skip-action-mailer --skip-action-mailbox --skip-active-storage --skip-test -d mysql
「--skip-turbolinks」の引数はRails7からなくなりました。また、Storageなどを使用する場合は引数から削除してから実行してください。
1. config/database.yml
default: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: # mysql_config --socketで確認できる # Ubuntu版 socket: /var/run/mysqld/mysqld.sock # CentOS版 socket: /var/lib/mysql/mysql.sock development: <<: *default database: データベース名 username: ユーザー名 password: パスワード
この時点で「bin/rails s」のコマンドで実行することが可能です。
2. コピペ作業 - その1
app\controllersのコピペ app\modelsのコピペ app\viewsのコピペ slimを使用している場合はapp\views\layouts\application.html.erbを削除する app\assets\stylesheetsにcssファイルだけをコピペ
3. JavasScript
JavasScriptは大きく変更されています。app\javascriptに仮にflash.jsを設置した場合はconfig\importmap.rbに次の行を追記します。
[config\importmap.rb]
pin "flash", preload: true
そして、開発時のビュー側では
= javascript_include_tag 'application'
ではなく次のようにします。
= javascript_importmap_tags
※この記述式はSlim方式
詳細は次のリンクを確認して下さい。
How to add custom JS file to new rails 7 project (Stack Overflow)
4. DELETEの確認ダイアログ
DELETEの確認ダイアログでは破壊的な仕様変更が行われています。
// Raila6はコレで動作する = link_to '削除', fsjs_account, method: :delete, data: { confirm: "\n#{fsjs_account.name} を削除します。よろしいですか?" }, class: 'btn btn-danger' // Rails7はこのようにしないと動作しない = button_to '削除', fsjs_account, method: :delete, form:{ data: { turbo_confirm: "\n#{fsjs_account.name} を削除します。よろしいですか?" }}, class: 'btn btn-danger'
link_toはダメ。data:{confirm:""}は form:{data:{turbo_confirm:""}} に変更する必要がある。ですので基本的にturbo-railsが必要になります。ただ、turbo-railsが嫌いな方がいると思いますので、手動でDELETEをする場合は次のJavaScriptコードを参考にして下さい。
// AjaxでDELETEを行う function ajax_delete(msg, url, jump){ if (confirm(msg)){ var xmlhttp = new XMLHttpRequest(); // イベント xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { window.location.href = jump; } } // トークン var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); // サーバにHTTPリクエストを送信 xmlhttp.open("DELETE", url, true); xmlhttp.setRequestHeader("Content-Type" , "x-www-form-urlencoded"); xmlhttp.setRequestHeader("X-CSRF-Token", token); // 上記のトークンで動作しない場合は次のトークンも試してください。 // ※フレームワークによって名称が異なる // xmlhttp.setRequestHeader("X-CSRFToken", token); xmlhttp.send(''); } }
これも嫌な方は data:{confirm:""} のまま動作するRails6が吐き出したコードを置いておきますね。flash_hide()以下は私の追記コードです。
5. コピペ作業 - その2
// 以下の2つは変更点だけを修正する config\environments\development.rb config\environments\production.rb config\locales\ja.ymlのコピペ config\locales\kaminari.ja.ymlのコピペ // このファイルも変更点だけを修正する config\application.rb --- config.time_zone = 'Asia/Tokyo' config.i18n.default_locale = :ja 本番運用で必要であれば ・config.hosts ・config.active_storage.routes_prefix なども設定する ---- db\のコピペ public\のコピペ (任意)storage\のコピペ
6. 非推奨の警告 - to_s(:delimited)
ビューとコントローラーの両方で次の非推奨の警告が発生する場合があるので修正しておきます。to_s(:delimited)をto_fs(:delimited)に変更します。
※grepで置換すると数秒で作業完了です。
7. 廃止 - URI.unescape
URI.unescapeをCGI.escapeに変換するだけです。
※こちらはRuby3.0.0から廃止されました。
8. Active Storage - 移行ガイド
初期状態では次のようなエラーが必ず発生します。
Can't resolve image into URL: undefined method `service_name'
Storageを使用している場合は次のコマンドを実行する必要があります。
// このアップデートが必須です。 bin/rails active_storage:update // 次はどちらかを選んでください。 bin/rails db:migrate RAILS_ENV=production bin/rails db:migrate RAILS_ENV=development
それでも、次のエラーが発生する場合は
config/application.rbの中身のrequireが次のようになっているか確認して下さい。私の場合は「require "action_text/engine"」が抜けていました。
[config/application.rb]
require_relative "boot" require "rails" # Pick the frameworks you want: require "active_model/railtie" require "active_job/railtie" require "active_record/railtie" require "active_storage/engine" require "action_controller/railtie" # require "action_mailer/railtie" # require "action_mailbox/engine" require "action_text/engine" require "action_view/railtie" require "action_cable/engine" # require "rails/test_unit/railtie"
ここまで設定してもActive Storageの画像やPDF、CSVファイルなどが404になる場合は本番環境と開発環境のStorageが異なっている場合がありますのでご確認ください。
Active Storageのファイルへのリンクは次のようになりました。
// redirectはあってもなくても同じように動作します。 // 問題は12345と67890でこの部分が異なっています。 // ※もしかすると、config/master.keyが関係しているかも知れません。 (Rails6) <img src="/rails-demo/blobs/xxx--12345/hoge.jpg" /> (Rails7) <img src="/rails-demo/blobs/redirect/xxx--67890/hoge.jpg" />
「/rails-demo」の部分についてはconfig/application.rbでconfig.active_storage.routes_prefix = '/rails-demo'にしています。
以上となります。お疲れさまでした。
関連記事
- Apache + PassengerでRailsとPHPを共存する [WSL/Ubuntu環境]
- Rails + React + AjaxでCRUDのサンプルプロジェクト [Hello World]
- NginxでPHP7(PHP-FPM)を動作させる [CentOS]
- MariaDBでRailsプロジェクトを作成する [WSL/Ubuntu環境]
- Rails6のプロジェクト作成時の「RAILS_ENV=development environment is not defined in config/webpacker.yml, falling back to production environment」のエラー対策
前の記事: | Vuexの使い方 [Rails] |