rails
Ruby on Rails
Topics
- rails 7.2からrails 8.0への移行(アップデート、アップグレード)で必要な作業
- rails 7.2で追加されたGitHubワークフローの設定ファイルci.ymlの内容について
- 既存のRailsアプリへのDev Containerの導入
- 既存のRailsアプリへのRuboCopの導入
- 既存のRailsアプリでのDependabotへの対応
- 既存のRailsアプリへのBrakemanの導入
- Rails 7.1では、パスワードに関してエラーメッセージの種類が増えた
- rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業
- railsが挿入するfield_with_errorsの要素がBootstrapのinput-groupの表示を乱す問題
- Railsで複数のセッションを用いたintegration testを行う方法
rails 7.2で追加されたGitHubワークフローの設定ファイルci.ymlの内容について
rails 7.2では、新規アプリに対してデフォルトでGitHubワークフローの設定ファイルであるci.ymlが生成されるようになりました。そこで、このci.ymlの内容について簡単に解説します。
なお、ci.ymlの最新のテンプレートはこちらでご覧になれます。
scan_ruby
bin/brakeman
コマンドを実行するジョブです。
Railsの一般的なセキュリティ脆弱性がないかどうかチェックします。
scan_js
bin/importmap audit
コマンドを実行するジョブです。
利用しているJavaScriptパッケージにセキュリティ上の脆弱性がないかどうかチェックします。
lint
bin/rubocop
コマンドを実行するジョブです。
Rubyの静的コード解析を行い設定されているルールに準拠しているかどうかチェックします。
test
bin/rails test
コマンドを実行するジョブです。なお、skip_system_testオプションが無効であれば、システムテストも実行します。
既存のRailsアプリへのDev Containerの導入
Rails 7.2においてDev Container設定を生成する機能が追加されました。 例えば既存アプリでは、以下のコマンドで既存アプリ用のDev Container設定を生成できるようになりました。
rails devcontainer
生成した設定は、Visual Studio Codeで利用でき、Dev Containerを利用した既存アプリの開発が可能となります。 必要となるソフトウェアのインストール等、Dev Containerでの開発を開始するための手順についてはDev Containerでの開発ガイドが参考になります。
なお、Visual Studio Code以外のエディタでもDev Containerで開発できるようにするべくDev Container CLIというツールの開発が進んでいますが、2024年12月現在では、ポートフォワーディングに対応していないなど、今のところはまだまだ開発途中のツールであり、実開発に投入するにはまだ早い段階である印象です。
既存のRailsアプリへのRuboCopの導入
Rails 7.2からRuboCopが新規アプリケーションでデフォルトで有効になりました。 このTopicでは、7.1以前で作成した既存RailsアプリにRuboCopを後から導入して、RuboCopに関して7.2の新規アプリ相当の状態にセットアップする方法をご紹介します。
RuboCop (Omakase Ruby styling for Rails) のインストール
基本的にはrubocop-rails-omakaseの公式ドキュメントのインストール手順に従います。
まず以下のように、Gemfileのgroup :development, :test
のところにrubocop-rails-omakaseを追加します。
group :development, :test do
# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
gem "rubocop-rails-omakase", require: false
end
次にbundle install
を実行して、RuboCop等をインストールします。
bundle install
さらに、必須ではありませんが、bin/rubocop
でRuboCopを実行できるように、以下のコマンドを実行します。
bundle binstubs rubocop
最後に.rubocop.yml
という名前でファイルを作成し、以下の内容を記述します。
# Omakase Ruby styling for Rails
inherit_gem:
rubocop-rails-omakase: rubocop.yml
以上でRuboCop (Omakase Ruby styling for Rails) のセットアップが出来ました。
ローカル環境でのbin/rubocopの実行とその結果に対する対応の進め方
以下のコマンドでbin/rubocopを実行でき、omakaseのチェックを行えます。
bin/rubocop
このチェックでの指摘事項が多かった場合、以下のオプションを付けて実行することで、
無視設定を記述した.rubocop_todo.yml
というファイルが作成され、
.rubocop.yml
にもこの無視ファイルを参照する設定が追加されますので、
とりあえず全ての指摘事項を無視するように設定が出来ます。
bin/rubocop --auto-gen-config
設定が出来たら、bin/rubocop
を実行して、とりあえず指摘事項の数が0となることを確認します。
1つずつ指摘事項へ対応
ここから先は、以下の手順を繰り返します。
-
.rubocop_todo.yml
から1項目を削除 -
bin/rubocop
を実行して指摘内容を確認して対応bin/rubocop -a
もしくはbin/rubocop -A
を実行して自動修正できるものは自動修正し、その修正内容で問題ないことを確認- 自動修正できなかったものは手作業で修正・確認
- 特定のファイルのみチェックを回避する場合は、
.rubocop.yml
にてExclude:
を用いて設定 - ソースコードの特定の箇所(行)のみチェックを回避する場合は、ソースファイルのコメントに
# rubocop:disable
等を用いて設定 - 指摘内容に対応する規則を完全に採用しない場合には、
.rubocop.yml
にてEnabled: false
の記述を用いて規則を無効にする
1項目ずつ対応を進め、.rubocop_todo.yml
の中身が無くなったら、.rubocop_todo.yml
を削除すると共に、.rubocop.yml
内で.rubocop_todo.yml
を参照している設定を削除します。ここまで終わればRuboCopの諸規則への対応は完了となります。お疲れ様でした。
GitHubワークフロー(CI)でのrubocopの実行
.github/workflows/ci.ymlに相当するファイルがなければ作成します。 この.ymlファイルを編集して、以下のようにjobsの下にlintジョブを追加します。
注意点
timeout-minutes:
の設定は、実行時間に対して十分余裕を持たせて下さい。ruby-version: .ruby-version
という設定は、プロジェクトルートにある.ruby-versionという名前のファイルで指定されているrubyのバージョンという意味になります。この設定について詳しくはこちらのTopicをご覧下さい。-f github
オプションは、出力フォーマットをGitHub Actionsに適したものにするオプションです。
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Lint code for consistent style
run: bin/rubocop -f github
公式情報
- RuboCopのその他の詳細についてはRuboCop公式ドキュメントをご覧ください。
- Omakase Ruby styling for RailsのRuboCop設定の最新の内容はGitHubで確認出来ます。なお、最新ではなくインストールしたバージョンのRuboCop設定内容をご覧になりたい場合は、GitHubの操作でTagsから当該バージョンを選択するようにして下さい。
既存のRailsアプリでのDependabotへの対応
Rails 7.2から新規アプリケーションにおいてDependabotがデフォルトで有効になりました。
具体的には、rails new
で生成される新規アプリにおいて、Dependabotの設定ファイルである.github/dependabot.yml
が生成されるようになりました。
Dependabotとは
Dependabotとは、GitHubのサービスであり、リポジトリで使用しているソフトウェアを最新の状態に保つことをサポートしてくれるサービスです。 具体的なDependabotの機能としては、以下の3つがあります。
- Dependabot alerts — リポジトリで使っている依存関係に内在する脆弱性について通知します。
- Dependabot security updates — 使っている依存関係のうち、既知のセキュリティ脆弱性があるものを更新するための pull request を自動的に生成します。
- Dependabot version updates — 依存関係を最新に保つための pull request を自動的に発行します。
Dependabotの詳細な理解にはクイックスタート ガイドなどをご利用ください。
既存のRailsアプリでのDependabotへの対応方法
脆弱性の通知機能(Dependabot alerts)は、GitHubのWebページから設定を変更するだけで利用できます。
脆弱性に関するpull requestの自動生成機能(Dependabot security updates)も、GitHubのWebページから設定を変更するだけで利用できますが、詳細な設定が必要な場合はdependabot.ymlを通して行います。
脆弱性対応以外も含めて最新の状態にするためのpull requestを自動生成する機能(Dependabot version updates)は、dependabot.ymlを通した設定が必要です。
(参考)デフォルトのdependabot.ymlの内容
このリンク先で閲覧できるrails new
で生成される新規アプリのdependabot.ymlの設定内容は、既存アプリでも参考になるかもしれません。
このdependabot.ymlには、Rails 7.2の時点では、railsアプリで利用しているgemとGitHub Actions(GitHubのCI)で利用しているアクションを最新に保つための設定が記述されています。
既存のRailsアプリへのBrakemanの導入
Rails 7.2から新規アプリケーションにおいてBrakemanがデフォルトで有効になりました。 このTopicでは、7.1以前で作成した既存RailsアプリにBrakemanを後から導入して、Brakemanに関して7.2の新規アプリ相当の状態にセットアップする方法をご紹介します。
Brakemanのインストール
まず以下のように、Gemfileのgroup :development, :test
のところにbrakemanを追加します。
group :development, :test do
# Static analysis for security vulnerabilities [https://brakemanscanner.org/]
gem "brakeman", require: false
end
次にbundle install
を実行します。
bundle install
以上でBrakemanのインストールが出来ました。
さらに、必須ではありませんが、bin/brakeman
でBrakemanを実行できるように、以下のコマンドを実行します。
bundle binstubs brakeman
ローカル環境でのBrakemanの実行
以下のコマンドでBrakemanを実行でき、デフォルトのチェックを行えます。
bin/brakeman
全てのチェックを実行する場合には、以下のオプション付けて実行します。
bin/brakeman -A
警告の無視に関する設定と管理を行う場合は、以下のオプション付けて実行します。
bin/brakeman -I
以下のように、これら2つのオプションを同時に指定して実行することも出来ます。
bin/brakeman -IA
なお、Brakemanの詳細については公式ドキュメントをご覧ください。 また、brakemanコマンドのオプションについては日本語訳もあります。
GitHubワークフロー(CI)でのBrakemanの実行
.github/workflows/ci.ymlに相当するファイルがなければ作成します。
この.ymlファイルを編集して、以下のようにjobs
の下にscan_ruby
ジョブを追加します。
ymlファイルの設定に関する注意点
timeout-minutes:
の設定は、実行時間に対して十分余裕を持たせて下さい。- 「
ruby-version: .ruby-version
」という設定は、プロジェクトルートにある.ruby-versionという名前のファイルで指定されているrubyのバージョンという意味になります。この設定についての詳細はこちらのTopicをご覧下さい。
jobs:
scan_ruby:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Scan for common Rails security vulnerabilities using static analysis
run: bin/brakeman --no-pager
bundle binstubs brakeman
を用いるやり方に更新しました。
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
基本的にはRailsガイドの手順に従えば良いと思います。
ガイドの手順にもありますが、ぜひ
bin/rails app:update
コマンドを活用しましょう。rails 8.0への移行で対応が必要そうな個別の作業について、以下のコメントでそれぞれ取り上げますので、ご参考になれば幸いです。
不要であればアイコン画像の削除
bin/rails app:update
コマンドを実行すると以下の2つのアイコン画像ファイルがpublic/
に作成されますが、これら2つのファイルは、
rails new
で生成される新規railsアプリ用のファイルであるため、既存アプリでは単純に削除してしまい、 従来通りのアイコン画像とアイコン設定(faviconやapple-touch-icon)を用いれば大丈夫です。 (もちろん、既存アプリにおいてアイコン設定が適切に行われている場合の話です。)より詳細な情報はrails 7.2への移行におけるアイコン画像のコメントをご覧ください。
Rails 8.0への移行におけるActive Storageのmigration
bin/rails app:update
コマンドを実行すると以下の3つのファイルがdb/migrate/
に作成されることがありますが、Active Storageをまだ使用したことがないアプリケーションでは、 これら3つのファイルは単純に削除してしまっても良いはずです。
詳しくは、「Rails 7.1への移行におけるActive Storageのmigration」のコメントをご覧ください。
Rails 8.0ではfilter_parametersに:cvvと:cvcが追加された
rails new
で生成されるconfig/initializers/filter_parameter_logging.rbにおいて、 Rails 8.0でconfig.filter_parametersに:cvv
と:cvc
が追加されました。 この追加に関するプルリクエストはこちらです。セキュリティの観点からは、確かにクレジットカードのCVCとCVVをフィルタすることは適切であるように思いますので、既存アプリにおいても:cvvと:cvcを追加すると良さそうです。
Rails 8.0におけるdeprecation関連の設定の削除
rails new
で生成されるconfig/environments/test.rbと同development.rbにおいて、 7.2以前は以下の設定用コードが存在していましたが、 このプルリクエストのマージによって削除されました。削除された理由は、当該プルリクエストによると、アプリが新規生成された直後は非推奨の問題と無縁であるということからのようです。 ですので、非推奨の問題が出てくる可能性のある既存アプリにおいては適切な設定をしたままにしておくのが良さそうです。
Rails 8.0におけるpublic_file_server.headersの設定の変更
rails new
で生成されるconfig/environments/test.rbと同development.rbにおいて、 このプルリクエストのマージによって、config.public_file_server.headers
のキーが以下のように小文字になりました。変更された理由はRack 3への対応のためですので、既存アプリでも設定を変更するのが良さそうです。
Rails 8.0におけるquery_log_tags_enabled
config.active_record.query_log_tags_enabled
は、SQLクエリのログに実行時情報のコメントを付加する機能を有効にするかどうかの設定です。rails new
で生成されるconfig/environments/development.rbにおいて、 8.0からは以下のようにこの設定が有効になるコードになりました(この変更のPR)。 ちなみに、default値は7.2から変わらずfalseですので、 development.rb内の当該設定を意図的に変更しなければ、既存アプリの挙動が勝手に変わることはありません。確かにdevelopment環境において便利そうな機能ですので、8.0へのアップデートを機に、有効にしても良いかもしれません。
Rails 8.0におけるassets.quiet
config.assets.quiet
は、アセット関連リクエストのログ出力を無効にするかどうかの設定です。後述のように、Rails 8.0.0でtrueにする以下の設定が削除されましたが、復活させるPRが出ていますので、既存アプリで削除するかには慎重な判断が必要かもしれません。rails new
で生成されるconfig/environments/development.rbにおいて、 8.0.0と8.0.1ではこの設定が削除されています(この変更のPR)。 しかし、この設定を削除するとターミナル出力がとっちらかるので設定を復活させるというPRがマージ済みですので、今後のバージョンでは設定が復活します。Rails 8.0におけるaction_controller.perform_cachingとaction_mailer.perform_caching
config.action_controller.perform_caching
とconfig.action_mailer.perform_caching
は、両方ともキャッシュ機能を有効にするかどうかの設定です。rails new
で生成されるconfig/environments/test.rbにおいて、 8.0からは以下のようにこれらの設定を無効にするコードが削除されました(この変更のPRとこの変更のCommit)。公式として8.0からはテスト環境ではキャッシュが効いた状態を標準とするということだと思いますので、既存アプリでも同じ設定変更、つまり、設定の削除をしても良いかもしれません。
Rails 8.0におけるassets.compile
config.assets.compile
は、動的なSprocketsコンパイルを有効にするかどうかの設定です。rails new
で生成されるconfig/environments/production.rbにおいて、 8.0からは以下のようにこの設定が削除されているのですが(この変更のPRとこの変更のCommit)、 これは8.0からrails new
で生成されるアプリのアセットパイプラインのデフォルトがPropshaftになったことに起因するものです。ですので既存アプリは、Propshaftへ移行する前はこの設定は削除しない方が良いと思われます。
Rails 8.0におけるpublic_file_server.headersとassume_ssl
rails new
で生成されるconfig/environments/production.rbにおいて、 8.0からは以下の設定2つが追加されているのですが(この変更のPRとこの変更のCommit)、 これは8.0からrails new
で生成されるアプリでKamal 2対応が行われていることに起因するものです。ですので既存アプリでは、Kamal 2対応をしないのであればこれらの設定の追加はしなくても良いと思われます。
Rails 8.0におけるsilence_healthcheck_path
config.silence_healthcheck_path
は、ログ出力を抑制すべきヘルスチェックのパスを指定する設定です。rails new
で生成されるconfig/environments/production.rbにおいて、 8.0からは以下のようにこの設定を行うコードが追加されました(この変更のPRとこの変更のCommit)。ヘルスチェックでログが詰まる問題が起きている場合や見やすさなどの理由でヘルスチェックのログを抑制をしたい場合は既存アプリでも同じ設定変更、つまり、設定の追加をしても良いかもしれません。
Rails 8.0におけるaction_mailer.perform_caching
config.action_mailer.perform_caching
は、メーラーテンプレートでフラグメントキャッシングを行うかどうかの設定です。rails new
で生成されるconfig/environments/production.rbにおいて、 8.0からは以下のようにこの設定を行うコードが削除されました(この変更のPRとこの変更のCommit)。このキャッシングを無効にするコードの削除により、メーラーテンプレートでのフラグメントキャッシングが有効になります。既存アプリでもメーラーテンプレートでのフラグメントキャッシングを有効にしたい場合は、このコードの削除により可能です。
Rails 8.0におけるactive_record.attributes_for_inspect
config.active_record.attributes_for_inspect
は、Active Recordオブジェクトのinspectに関わる設定です。rails new
で生成されるconfig/environments/production.rbにおいて、 8.0からこの設定を行う以下のコードが追加されました(この変更のPR)。このコードの追加により、production環境ではinspectの結果に基本的にidのみが含まれるようになります。この設定はproduction環境でのパフォーマンスの悪化をさけるための変更に端を発していますので、既存アプリでもこのコードを追加すると良いかもしれません。
Rails 8.0におけるlogger
config.logger
は、Railsアプリで用いるロガーの設定です。rails new
で生成されるconfig/environments/production.rbにおいて、 8.0からこの設定について以下の変更が行われました(この変更のPRその1とPRその2)。この変更により、Kamralを用いたproduction環境ではタイムスタンプが二重に表示されなくなります。既存アプリでも、production環境でタイムスタンプが二重になっている場合には、この変更を行ってタイムスタンプが1つになるようにすると良いかもしれません。