rails
Ruby on Rails
Topics
- 既存のRailsアプリへのBrakemanの導入
- Rails 7.1では、パスワードに関してエラーメッセージの種類が増えた
- rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業
- railsが挿入するfield_with_errorsの要素がBootstrapのinput-groupの表示を乱す問題
- Railsで複数のセッションを用いたintegration testを行う方法
- Ruby on Railsのサポート終了日(各バージョンのEOL)
- WSL2上にてrails serverで立ち上げたサーバに別デバイスからのアクセスを可能にする方法
- rails 7.0からrails 7.1への移行(アップデート、アップグレード)で必要な作業
- rails 7.0.4 で pg 1.5 を使うと警告が出る問題
- Railsを用いた運用中のサービスのアップグレードの仕方
Rails 7.1では、パスワードに関してエラーメッセージの種類が増えた
Rails 7.1に取り込まれたこちらのプルリクエストによって、
ActiveModel::SecurePassword
のhas_secure_password
メソッドを利用している場合のパスワードのバリデーションにおいて、
パスワード文字列が72バイト以内かどうかのチェックが行われるようになりました。
そして、72バイトを超えている場合には、password_too_long
という新しい種類のエラーが出るようになりました。
この変更に伴って、日本語表示のRailsアプリでは、password_too_long
のエラーメッセージの日本語訳を用意する必要があります。
具体的には、以下の階層の所に以下のような日本語訳が必要となります。
ja:
errors:
messages:
password_too_long: が長すぎます
rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業
基本的にはRailsガイドの手順に従えば良いと思います。
ガイドの手順にもありますが、ぜひbin/rails app:update
コマンドを活用しましょう。
rails 7.2への移行で対応が必要そうな個別の作業について、以下のコメントでそれぞれ取り上げますので、ご参考になれば幸いです。
rails 7.2におけるannotate_rendered_view_with_filenames
annotate_rendered_view_with_filenamesは、rails 6.1で追加されたビューのテンプレートの開始と終了に対応するHTMLコメントを挿入する機能です。
rails new
で生成されるconfig/environments/development.rbにおいて、
7.1以前はこの機能を有効化する以下のコードがコメントアウトされていましたが、
7.2からは以下のように有効になるコードになりました(この変更のPR)。
ちなみに、default値は7.1以前から変わらずfalseですので、
development.rb内の当該設定を意図的に変更しなければ、既存アプリの挙動が勝手に変わることはありません。
config.action_view.annotate_rendered_view_with_filenames = true
確かにdevelopment環境において便利そうな機能ですので、7.2へのアップデートを機に、使い始めてみるのも良いかもしれません。
rails 7.2におけるpublic_file_server.enabled
rails new
で生成されるconfig/environments/test.rbにおいて、
7.1以前は以下の設定用コードが存在していましたが、
このプルリクエストのマージによって削除されました。
config.public_file_server.enabled = true
削除された理由は、このプルリクエストによると、default値がtrue、かつ、全てのenvironment(test、development、production)の間で設定値に違いが無いということからです。
ですので、既存アプリにおいても、設定値をtrue
としている場合には、この設定用コードは削除してしまっても良いかもしれません。
rails 7.2ではfilter_parametersに:emailが追加された
rails new
で生成されるconfig/initializers/filter_parameter_logging.rbにおいて、
rails 7.2でconfig.filter_parametersに:email
が追加されました。
この追加に関するプルリクエストはこちらです。
Rails.application.config.filter_parameters += [
- :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
+ :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
]
セキュリティや個人情報保護の観点からは、確かにメールアドレスをフィルタすることは適切であるように思いますので、既存アプリにおいても:emailを追加すると良さそうです。
ちなみに、デバッグ作業などでメールアドレスを確認するときには少し不便になるような気もしますが、 emailへの直接の読み書きが疎外されるわけではありませんし、 またpluckなどの活用もすればデバッグの支障にはさほどならないような気がします。
rails 7.2でのconfig/puma.rbの大幅な更新
rails new
で生成されるconfig/puma.rbが大幅に更新されました。
主要な変更点は以下の通りです。
threads
の指定方法の変更: リリースノート:Pumaのデフォルトのスレッド数が新しくなった、PR #50450 、PR #50669pidfile
の変更: PR #50644、PR #50669、commit 57a6916environment
の削除: PR #52541- production環境での
workers
の削除: commit 142e6ab - production環境での
preload_app!
の削除: PR #52541 - development環境での
worker_timeout
の削除: PR #52541
rails 7.2への移行におけるActive Storageのmigration
bin/rails app:update
コマンドを実行すると以下の3つのファイルがdb/migrate/
に作成されることがありますが、
Active Storageをまだ使用したことがないアプリケーションでは、
これら3つのファイルは単純に削除してしまっても良いはずです。
- xxx_add_service_name_to_active_storage_blobs.active_storage.rb
- xxx_create_active_storage_variant_records.active_storage.rb
- xxx_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
より正確に言うと、データベースにactive_storage_blobsテーブルが存在していない場合は、
これら3つのファイルは単純に削除してしまっても良いはずです。
その理由として、これら3つのファイルはデータベースのactive_storage_blobsテーブルに対して影響を与えるものであり、
table_exists?(:active_storage_blobs)
がfalseを返すと何もせずにreturnする処理が3つのファイル全てに記述されているからです。
ご自身のRailsアプリケーションのデータベースにactive_storage_blobsテーブルが存在するかの確認はbin/rails console
を実行して、
以下のようにコマンドを実行することで行えます。
結果がfalse
であればactive_storage_blobsテーブルは存在していない、つまり前述の3つのファイルは削除で大丈夫のはずです。
foobar(dev)> ActiveRecord::Base.connection.table_exists? :active_storage_blobs
=> false
ちなみに、データベースにあるテーブルの一覧を見たい場合にはbin/rails console
で
ActiveRecord::Base.connection.tables
を叩くことでテーブルの一覧を確認できます。
rails 7.2で追加されたブラウザバージョン指定機能と406-unsupported-browser.html
bin/rails app:update
コマンドを実行するとpublic/に406-unsupported-browser.html作成されます。
このHTMLフィアルは、rails 7.2で追加されたブラウザバージョン指定機能が指定範囲外のブラウザに対して送るファイルです。
なお、既存アプリでは、この機能の利用を始めないのであれば、念のため406-unsupported-browser.htmlを置くだけ置いておくという対応で良いように思います。
rails 7.2ではassertionがないテストに対して警告が出るようになった
現象
rails 7.2では、Minitestを使ったテストに関して、assert系メソッドが1つも呼ばれないテストがあると"Test is missing assertions"という警告が出るようになりました。
警告が出ないようにする方法
各テストでassert系メソッドが最低1回は実際に呼ばれるようにして下さい。
例外が起きないことを確認するテストではassert_nothing_raised
メソッドを用いて下さい。
なお、警告の回避方法を含め、こちらの記事が参考になるかもしれません。
関連するプルリクエストとコミット
この機能はPR #51625で導入され、このときはrailsアプリの設定によって挙動を変えられるようになっていました。 その後、commit 6a6c7e6によって機能が単純化され、単に常に警告が出力されるだけになりました。 その後、PR #51693で関係するコードを綺麗にする作業などが行われています。
rails 7.2への移行におけるアイコン画像
bin/rails app:update
コマンドを実行すると以下の2つのアイコン画像ファイルがpublic/
に作成されますが、
これら2つのファイルは、rails new
で生成される新規railsアプリ用のファイルであるため、既存アプリでは単純に削除してしまい、
従来通りのアイコン画像とアイコン設定(faviconやapple-touch-icon)を用いれば大丈夫です。
(もちろん、既存アプリにおいてアイコン設定が適切に行われている場合の話です。)
- icon.png
- icon.svg
ちなみに、以下の通りrails 7.2では、新規アプリのアイコン設定が大幅に更新されています。 rails 7.2のこの新たなアイコン設定は、既存アプリにおいてもアイコン設定を見直す際に役立つかもしません。
(参考)rails 7.2.1の新規アプリのアイコン設定
以下が、新規アプリ用のテンプレートファイルからコピーしたrails 7.2.1の新規アプリのアイコン設定です。
<link rel="manifest" href="/manifest.json">
<link rel="icon" href="/icon.png" type="image/png">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/icon.png">
新たなアイコン画像ファイルによるアイコン設定に関与しているプルリクエストは、 PR #50526と PR #50629です。 3つのアイコン画像ファイル(apple-touch-icon-precomposed.png、apple-touch-icon.png、favicon.ico)が削除され、 2つのアイコン画像ファイル(icon.png、icon.svg)が追加されています。 また、manifestに関しては、PWAに関する新機能に関連して導入されています。
railsが挿入するfield_with_errorsの要素がBootstrapのinput-groupの表示を乱す問題
問題の内容
フォームヘルパーで作成したフォームの標準の挙動として、
railsは、バリデーション・エラーが起きたフォーム要素を、field_with_errors
クラスを指定したdiv要素で囲みます。
つまり、バリデーション・エラーの有無によって、HTMLの階層構造が変わってしまいます。
その一方で、BootstrapのInput groupは、input-group
クラスを指定した要素の直接の子要素としてフォーム要素があることを前提としています。
そのためバリデーション・エラー時に、input-group
を指定した要素とフォーム要素の間にfield_with_errors
クラスのdiv要素が割り込むことで、Input groupの表示を乱してしまいます。
この問題に対し、インターネット上の情報では、
display: contents;
を利用する方法や
config.action_view.field_error_proc
の設定を変更する方法が紹介されていましたが、
私が試した限りでは問題の解決に至りませんでした。
そこで以下では、Input groupの利用を諦めて、Input groupに似た表示を他のBootstrapの機能で実現する方法をご紹介します。
なお、この問題に関して別の何か良い方法をご存じの方がいらっしゃいましたら、コメントをいただけると嬉しいです。
Bootstrapにおいて、Input groupに似た表示をgridで作成する方法
例として、Input groupを利用した以下のフォームの一部分を考えます。
<div class="input-group">
<span class="input-group-text">@</span>
<%= f.text_field :username, class: 'form-control' %>
</div>
このフォームの一部分に近い表示を実現する例が以下のコードです。Input groupを利用した表示と比べると、「@」を囲む枠線は無くなりますが、文字やフォームの位置関係は近いものを実現できます。なお、ブラウザの画面幅をいろいろと変えた場合でも、位置関係の近さは大丈夫なはずです。
<div class="row gx-1">
<div class="col-auto col-form-label">@</div>
<div class="col">
<%= f.text_field :username, class: 'form-control' %>
</div>
</div>
このコードで利用しているBootstrapのクラスについて少し解説します。
まず横幅のバランスに関しては、以下のクラスを利用しています。
col-auto
:内容の幅、つまり、上述のコードではフォームの左にある文字列である「@」の幅に基づいたカラムの幅になります。col
:残っている幅を均等に割り付けた幅になります。例えばcol
クラスのカラムが2つあれば残りの幅が2分割されて均等に割り付けられます。上述のコードではcol
クラスのカラムは1つですので、左にある「@」のカラムの幅を除いた残りの幅が全てこのtext_field
のカラムに割り付けられます。
次に文字の位置(この例では「@」の位置)は、以下のクラスで調整しています
col-form-label
:指定することでフォームと上下位置をそろえられます。gx-*
:ガターを調整することで「@」とフォームの間の距離を調整し左右位置を調整しています。なお、左右位置を細かく調整したい場合にはmarginで直接細かく指定しても良いかもしれません。
(参考)Input groupに似せることよりもgridのカラム幅の指定を優先する場合
グリッドにおいて要素間の左右位置をそろえたいとき等では、col-auto
を使わずに、以下のコードのようにカラム幅を指定する方法もあります。
このような場合では、文字列の左右位置の調整にtext-end
クラスやtext-center
クラスが役立つかもしれません。
<div class="row gx-1">
<div class="col-2 col-form-label text-end">@</div>
<div class="col-10">
<%= f.text_field :username, class: 'form-control' %>
</div>
</div>
コードの動作確認をしたgemのバージョン
- rails (7.1.3.4)
- bootstrap (5.3.3)
Railsで複数のセッションを用いたintegration testを行う方法
別々のブラウザから複数のユーザがログインするような状況を再現したintegration testを実装しようとするときなど、 ユーザごとにセッションが必要になるなどして、 1つのテスト内で複数のセッションが必要になることがあります。
Ruby on Railsのintegration testでは、 標準でこのような複数のセッションを用いるテストに対応しており、 公式ドキュメントの中では、ActionDispatch::IntegrationTestのAPIドキュメントに説明があります。
複数のセッションを用いたintegration testの例
公式情報は上述のAPIドキュメントをご覧いただければと思いますが、一応こちらでも簡単な例を使ってintegration testで複数のセッションを用いる方法をご紹介します。
ここではテスト内容として、ログインしているユーザが列挙されるページをテストすることを想定してテストコードを考えます。 具体的には、ユーザ1がログインするとこのページにユーザ1が現れ、 続けてユーザ2がログインすると今度はユーザ1とユーザ2の両方がページに現れることを確認します。
シンプルにopen_session()でセッションを作って用いる場合の例
複数のセッションを用いる場合に鍵となるメソッドは、open_session()です。 このメソッドはセッションのオブジェクト返しますので、必要なセッションの回数分呼び出せば、必要な数のセッションが作成出来ます。 セッションを複数作成したら、各セッションのオブジェクトのインスタンスメソッドとしてget()やassert_response()を呼び出すことで、 セッションを指定してアクションやアサーションを実行できます。
以下にサンプルコードを示します。
require "test_helper"
class MultipleSessionTest < ActionDispatch::IntegrationTest
test "login users page" do
user1 = users(:one)
user2 = users(:two)
sess1 = open_session
sess2 = open_session
sess1.get login_path
sess1.assert_response :success
sess1.post login_path,
params: { {email: user1.email,
password: user1.password} }
sess1.assert_response :found
sess1.assert_redirected_to root_path
sess1.follow_redirect!
sess1.get login_users_path
sess1.assert_response :success
assert_match /@#{user1.username}/, sess1.response.body
assert_no_match /@#{user2.username}/, sess1.response.body
sess2.get login_path
sess2.assert_response :success
sess2.post login_path,
params: { {email: user2.email,
password: user2.password} }
sess2.assert_response :found
sess2.assert_redirected_to root_path
sess2.follow_redirect!
sess1.get login_users_path
sess1.assert_response :success
assert_match /@#{user1.username}/, sess1.response.body
assert_match /@#{user2.username}/, sess1.response.body
end
end
繰り返される処理をDSLのメソッドにまとめる例
上述のシンプルな例を見てみると、ログイン処理などで、対象とするセッションは異なるものの、ほぼ同じ処理が繰り返されていることが分かります。 こういった繰り返される処理は、特定のテストで用いるセッションのDSL (Domain-Specific Language) としてまとめることが出来ます。
以下のテストコードは、テストの手順や内容は上述のシンプルな例と同じですが、今度はこのDSLを用いてコードの繰り返しを排除したものになっています。なお、テストコードの読みやすさの観点でも、こちらの例の方が良くなっているのではないでしょうか。
require "test_helper"
class MultipleSessionWithDSLTest < ActionDispatch::IntegrationTest
test "login users page" do
user1 = users(:one)
user2 = users(:two)
sess1 = open_session_with_dsl
sess2 = open_session_with_dsl
sess1.login(user1)
sess1.get_login_users
assert_match /@#{user1.username}/, sess1.response.body
assert_no_match /@#{user2.username}/, sess1.response.body
sess2.login(user2)
sess1.get_login_users
assert_match /@#{user1.username}/, sess1.response.body
assert_match /@#{user2.username}/, sess1.response.body
end
private
module CustomDsl
def login(user)
get login_path
assert_response :success
post login_path,
params: { {email: user.email,
password: user.password} }
assert_response :found
assert_redirected_to root_path
follow_redirect!
end
def get_login_users
get login_users_path
assert_response :success
end
end
def open_session_with_dsl
open_session do |sess|
sess.extend(CustomDsl)
end
end
end
Ruby on Railsのサポート終了日(各バージョンのEOL)
railsの各バージョンについて、セキュリティアップデートが行われる期限(End-of-Life)は以下の通りです。
- 8.0.x - 2026/11/07
- 7.2.x - 2026/08/09
- 7.1.x - 2025/10/01
- 7.0.x - 2025/04/01
6.1.xは、以下の通りサポートが終了しています。
- 6.1.x - 2024/10/1
なお、railsのサポート期間に関するより詳細な情報については本家のメンテナンス・ポリシーを参照してください。
WSL2上にてrails serverで立ち上げたサーバに別デバイスからのアクセスを可能にする方法
背景
WindowsのWSL2環境でRailsアプリを開発しています。開発しているWebアプリに関してAppleのSafariブラウザでの動作確認が必要になりました。そこで、同一LAN内にあるiPhoneやiPadといった別デバイスから、WSL2環境においてrails server
コマンドで走らせたサーバへ、アクセスできるようにしました。
手順
LAN接続の設定
後述のファイアウォールの設定にて、プライベートネットワークに限定する設定をする場合には、Railsサーバを走らせているPCのLAN設定で、ネットワーク プロファイルをプライベートにしておきます。
WSL2で走っているLinuxのIPアドレスの確認
ifconfig
の出力のinet
のところなどで、WSL2で走っているUbuntuなどのLinux OS側のIPアドレスを確認し、転送先アドレスとして控えます。
LinuxのIPアドレスが正しいことの確認
まず、bin/rails server -b 0.0.0.0
でWSL2上でRailsサーバを起動します。
次に、このRailsサーバに、WSL2環境ではなくWindows上で普通に走っているブラウザから、先ほど調べたWSL2で走っているLinuxのIPアドレスに対し
http://(LinuxのIPアドレス):3000/
というようなアドレス(ここではポート番号を3000としていますが、別のポートをRailsサーバに用いている場合はそのポート番号に変更して下さい)でアクセス出来ることを確認します。
ここでアクセスに失敗するようでは何かしらが間違っていますので、まずはこのようにアクセス出来るようにしましょう。
ホストOSであるWindowsのIPアドレスの確認
ipconfig
などで、Windows側、つまり、ホストOS側のLAN上でのIPアドレスを確認し、転送元アドレスとして控えます。
ポートフォワーディングの設定
管理者権限で以下のコマンドを実行します。なお、特に理由が無ければ、転送元ポートは転送先ポートと同じ(3000)で大丈夫です。
netsh interface portproxy add v4tov4 listenaddress=<転送元(Windows)のIPアドレス> listenport=<転送元ポート> connectaddress=<転送先(Linux)のIPアドレス> connectport=<転送先ポート>
ファイアウォールの設定
Windowsのファイアウォールの設定にて、「受信の規則」として以下の設定を追加します。
- プロトコルの種類:「TCP」
- ローカルポート: 「特定のポート」「3000(転送元ポート)」
- リモートポート: 「すべてのポート」
なお、ファイアウォールの設定にて、プライベートネットワークに限定したり、テスト時以外は無効にしたりするなど、セキュリティには十分に配慮をして下さい。
接続確認
同一LAN内の別デバイスから、 http://(WindowsのIPアドレス):(転送元ポート)/ というようなアドレスでアクセス出来ることを確認します。
参考情報
別デバイスからhttpsでrails server
にアクセスする方法
前述の方法で別デバイスからhttpでアクセスできるようになりますが、httpsでアクセスする必要がある場合には、
local-ssl-proxy
を使ってhttpsをhttpに振り向けることで、httpsアクセスが可能になります。具体的な方法は以下をご覧ください。
なお別デバイスからhttpsでアクセスするには、前述のポートフォワーディングとファイアウォールの設定をhttpsのポート番号で行う必要があります。
rails 7.0からrails 7.1への移行(アップデート、アップグレード)で必要な作業
基本的にはRailsガイドの手順に従えば良いと思います。
ガイドの手順にもありますが、ぜひbin/rails app:update
コマンドを活用しましょう。
bin/rails app:update
コマンドの実行例
# bin/rails app:update
identical config/boot.rb
exist config
conflict config/application.rb
Overwrite /x/techtips/config/application.rb? (enter "h" for help) [Ynaqdhm] h
Y - yes, overwrite
n - no, do not overwrite
a - all, overwrite this and all others
q - quit, abort
h - help, show this help
d - diff, show the differences between the old and the new
m - merge, run merge tool
Overwrite /x/techtips/config/application.rb? (enter "h" for help) [Ynaqdhm]
force config/application.rb
identical config/environment.rb
exist config/environments
conflict config/environments/development.rb
Overwrite /x/techtips/config/environments/development.rb? (enter "h" for help) [Ynaqdhm]
force config/environments/development.rb
conflict config/environments/production.rb
Overwrite /x/techtips/config/environments/production.rb? (enter "h" for help) [Ynaqdhm]
force config/environments/production.rb
conflict config/environments/test.rb
Overwrite /x/techtips/config/environments/test.rb? (enter "h" for help) [Ynaqdhm]
force config/environments/test.rb
exist config/initializers
conflict config/initializers/assets.rb
Overwrite /x/techtips/config/initializers/assets.rb? (enter "h" for help) [Ynaqdhm]
force config/initializers/assets.rb
conflict config/initializers/content_security_policy.rb
Overwrite /x/techtips/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 /x/techtips/config/initializers/filter_parameter_logging.rb? (enter "h" for help) [Ynaqdhm]
force config/initializers/filter_parameter_logging.rb
identical config/initializers/inflections.rb
create config/initializers/new_framework_defaults_7_1.rb
conflict config/initializers/permissions_policy.rb
Overwrite /x/techtips/config/initializers/permissions_policy.rb? (enter "h" for help) [Ynaqdhm]
force config/initializers/permissions_policy.rb
remove config/initializers/cors.rb
exist bin
identical bin/rails
identical bin/rake
conflict bin/setup
Overwrite /x/techtips/bin/setup? (enter "h" for help) [Ynaqdhm]
force bin/setup
rails active_storage:update
Copied migration 20231128024504_add_service_name_to_active_storage_blobs.active_storage.rb from active_storage
Copied migration 20231128024505_create_active_storage_variant_records.active_storage.rb from active_storage
Copied migration 20231128024506_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.
Rails 7.1への移行におけるActive Storageのmigration
bin/rails app:update
コマンドを実行すると以下の3つのファイルがdb/migrate/
に作成されますが、
Active Storageをまだ使用したことがないアプリケーションでは、
これら3つのファイルは単純に削除してしまって良いはずです。
- xxx_add_service_name_to_active_storage_blobs.active_storage.rb
- xxx_create_active_storage_variant_records.active_storage.rb
- xxx_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
より正確に言うと、データベースにactive_storage_blobsテーブルが存在していない場合は、
これら3つのファイルは単純に削除してしまって良いはずです。
その理由として、これら3つのファイルはデータベースのactive_storage_blobsテーブルに対して影響を与えるものであり、
table_exists?(:active_storage_blobs)
がfalseを返すと何もせずにreturnする処理が3つのファイル全てに記述されているからです。
ご自身のRailsアプリケーションのデータベースにactive_storage_blobsテーブルが存在するかの確認はbin/rails console
を実行して、
以下のようにコマンドを実行することで行えます。
結果がfalse
であればactive_storage_blobsテーブルは存在していない、つまり前述の3つのファイルは削除で大丈夫のはずです。
irb(main):002> ActiveRecord::Base.connection.table_exists? :active_storage_blobs
=> false
ちなみに、データベースにあるテーブルの一覧を見たい場合にはbin/rails console
で
ActiveRecord::Base.connection.tables
を叩くことでテーブルの一覧を確認できます。
Rails 7.1でのaction_dispatch.show_exceptions
の変更への対応方法
対応の基本的な方向性
config.action_dispatch.show_exceptions
を今後のデフォルトとなる:rescuable
に設定してbin/rails test
でテストを実行します。テストの実行に問題が無く、:rescuable
の仕様で支障が無い場合はこれでOKです。
設定で:rescuable
を選択してテストを実行するとエラーが出るようになってしまった場合は、テストを修正するか、:rescuable
以外の設定値にします。元々true
と設定していた場合には:all
、false
と設定していた場合には:none
へと設定し直せば、以前の挙動と同じになり、エラーは出なくなるはずです。
より詳しい情報を紹介している記事
本件の背景やテストの修正方法など、より詳しい情報はこちらの記事をご覧下さい。
Rails 7.1で追加されたパスワード関連エラーメッセージへの対応
has_secure_password
を利用しているモデルがあり、かつ、英語以外のロケールへ対応している既存アプリでは、
rails 7.1で追加されたエラーの種類であるpassword_too_long
に対応するエラーメッセージの訳文を追加する必要があります。
(追加をしないとパスワードが長すぎた場合のエラーメッセージが英語で表示されます。)
なお、本件の詳細についてはこちらをご覧下さい。
rails 7.0.4 で pg 1.5 を使うと警告が出る問題
結論
railsのバージョンを7.0.5以上に上げてから、pg 1.5 にバージョンを上げれば、警告の問題は発生しません。
問題が発生したバージョン
- ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
- rails (7.0.4.3)
問題を引き起こした作業内容
bundle update
でpgのバージョンを1.4系から1.5系に上げた。
発生した問題
rails test
で以下のような警告が複数出るようになった。
PG::Coder.new(hash) is deprecated. Please use keyword arguments instead! Called from /usr/local/bundle/gems/activerecord-7.0.4.3/lib/active_record/connection_adapters/postgresql_adapter.rb:980:in `new'
rails 7.0.5のリリース後に行った対処
Gemfile
にて、pgは1.5以降、railsは7.0.5以降を使うように指定してから、bundle update
コマンドを実行した。
その後でrails test
を実行し、前述の警告が出ないことを確認した。
rails 7.0.5のリリース前に行った対処
Gemfile
に以下のように記述して、利用するpgを1.4系に留めるように指定した。
gem "pg", "~> 1.4.6"
rails本家の対応状況
- 4/24にissueが立った: https://github.com/rails/rails/issues/48046
- 4/25に修正がマージされた: https://github.com/rails/rails/pull/48048
- 5/25に修正が入ったv7.0.5がリリースされた: https://github.com/rails/rails/releases/tag/v7.0.5
昨日rails 7.0.5がリリースされました。
早速試したところ、rails 7.0.5とpg 1.5の組み合わせでは、前述の警告が出ないことを確認できました。
そこで、この結果を踏まえて、このTopicの先頭コメントの記述を更新しました。
Railsを用いた運用中のサービスのアップグレードの仕方
まずはRubyをアップグレード
「RubyのアップグレードとRailsのアップグレードは別々に行うのがよい方法です。最初にRubyを可能な限り最新版にアップグレードし、それからRailsをアップグレードします。」 Railsガイドより
次にRailsを1つずつアップグレード
「Railsのバージョンを変更する場合、マイナーバージョンを1つずつゆっくりと上げながら、その都度表示される非推奨機能の警告メッセージを上手に利用するのがベストです。」Railsガイドより
具体的には、以下の手順を繰り返す。
- テストを書き、テストがパスすることを確認する。
- 現時点のバージョンのパッチバージョンを最新のパッチに移行する。
- テストを修正し、非推奨の機能を修正する。
- 次のマイナーバージョンの最新パッチに移行する。
- マイナーバージョン以上を上げる場合、Gemfileに記載されているRailsのバージョンを更新した後に
bin/rails app:update
を実行して設定等を最新のバージョンに合わせる。参考:1.4 アップデートタスク、1.5 フレームワークのデフォルトを設定する
- マイナーバージョン以上を上げる場合、Gemfileに記載されているRailsのバージョンを更新した後に
Rails 7.2から新規アプリケーションにおいてBrakemanがデフォルトで有効になりました。 このTopicでは、7.1以前で作成した既存RailsアプリにBrakemanを後から導入して、Brakemanに関して7.2の新規アプリ相当の状態にセットアップする方法をご紹介します。
Brakemanのインストール
まず以下のように、Gemfileの
group :development, :test
のところにbrakemanを追加します。次に
bundle install
を実行します。以上でBrakemanのインストールが出来ました。
ローカル環境でのBrakemanの実行
以下のコマンドでBrakemanを実行でき、デフォルトのチェックを行えます。
全てのチェックを実行する場合には、以下のオプション付けて実行します。
警告の無視に関する設定と管理を行う場合は、以下のオプション付けて実行します。
以下のように、これら2つのオプションを同時に指定して実行することも出来ます。
なお、Brakemanの詳細については公式ドキュメントをご覧ください。 また、brakemanコマンドのオプションについては日本語訳もあります。
GitHubワークフロー(CI)でのBrakemanの実行
.github/workflows/ci.ymlに相当するファイルがなければ作成します。 この.ymlファイルを編集して、以下のように
jobs
の下にscan_ruby
ジョブを追加します。ymlファイルの設定に関する注意点
timeout-minutes:
の設定は、実行時間に対して十分余裕を持たせて下さい。ruby-version: .ruby-version
」という設定は、プロジェクトルートにある.ruby-versionという名前のファイルで指定されているrubyのバージョンという意味になります。この設定についての詳細はこちらのTopicをご覧下さい。