Skip to content

Ruby on Rails PR Digest - 2026年 1月

このページは rails/rails リポジトリにマージされたPull Requestを自動的に収集し、AIで要約したものです。

#56692 Improve diagnostics UI to make nested stack traces more discoverable

マージ日: 2026/1/30 | 作成者: @mctaylorpants

  1. 概要 (1-2文で)
    Rails のエラーページ(diagnostics ページ)で、ネストした例外のスタックトレースが「クリックで展開できること」に気づきやすくなるよう、UI に小さな矢印アイコンを追加する変更です。純粋に見た目と操作性だけの改善で、サーバサイドの挙動や API には影響しません。

  1. 変更内容の詳細

何を改善したか

  • 対象: ActionDispatch::DebugExceptions が出す diagnostics 用の HTML テンプレート
    • actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
    • actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
  • 「ネストした例外(cause 付きの例外)」のサマリーバーをクリックすると、スタックトレースが展開される UI がもともと存在していたが、
    • クリック可能であることが分かりづらい
    • スタックトレースが隠れていると気づきにくい
  • そのため、サマリーバーの端に「▶︎ のような矢印」を追加し、
    • 畳まれている時: 矢印が閉じた向き
    • 展開されている時: 矢印が回転して開いた向き という、よくあるディスクロージャ UI を導入しています。

想定される実装イメージ

PR 本文には画像のみですが、変更行数から推測すると、layout.erb に以下のような CSS/JS 的なコードが追加されている可能性が高いです(実際のクラス名・セレクタは例です):

erb
<style>
  .nested-exception-summary {
    cursor: pointer;
    display: flex;
    align-items: center;
  }

  .nested-exception-arrow {
    margin-right: 6px;
    transition: transform 0.15s ease-in-out;
  }

  .nested-exception-summary[aria-expanded="true"] .nested-exception-arrow {
    transform: rotate(90deg);
  }
</style>
erb
<div class="nested-exception-summary" data-behavior="toggle-nested" aria-expanded="false">
  <span class="nested-exception-arrow">▶</span>
  <span class="nested-exception-title"><%= h exception.class.name %>: <%= h exception.message %></span>
</div>
<div class="nested-exception-backtrace" hidden>
  <!-- スタックトレース -->
</div>
html
<script>
  document.addEventListener("click", function (e) {
    var summary = e.target.closest("[data-behavior='toggle-nested']");
    if (!summary) return;

    var expanded = summary.getAttribute("aria-expanded") === "true";
    summary.setAttribute("aria-expanded", String(!expanded));

    var panel = summary.nextElementSibling;
    if (!panel) return;

    if (expanded) {
      panel.setAttribute("hidden", "hidden");
    } else {
      panel.removeAttribute("hidden");
    }
  });
</script>

実際のパッチは 20 行程度の追加のため、これをもっと短くした形(既存のトグル処理にクラスを足して矢印を回転させるだけ、など)になっていると考えられます。

diagnostics.html.erb 側の変更

diagnostics.html.erb では、ネストした例外のサマリ部分の HTML に矢印用の要素やクラスが 1〜2 箇所追加・変更されている程度です。例:

erb
<div class="nested-exception-summary">
  <span class="nested-exception-arrow"></span>
  <%= h nested_exception.class.name %>: <%= h nested_exception.message %>
</div>

元々ある「クリックで展開」機能はそのまま利用しつつ、視覚的な「展開可能」インジケータを足しているだけです。


  1. 影響範囲・注意点
  • 影響範囲

    • 開発環境や本番で consider_all_requests_local = true などになっている場合に表示される、Rails のエラー・診断ページの UI のみ。
    • コントローラ・モデル・ビュー・ルーティングなどアプリケーション側のコードや挙動には一切影響なし。
    • Action Pack ライブラリのエラーページテンプレートのみが対象。
  • 後方互換性・破壊的変更

    • 見た目と UX の改善だけで、API や外部インターフェイスの仕様変更はないため、基本的には後方互換。
    • テンプレート HTML/CSS を前提に独自のスクレイピング・テスト・カスタムスタイルを当てている場合は、クラス名や要素構造の違いで影響が出る可能性はあります(一般的にはまれなケース)。
  • テスト・CHANGELOG

    • 視覚的な変更に限られるため、テストは追加されていません。
    • CHANGELOG も更新されていない(マイナーな UI 改善として扱われている)ため、リリースノートには載らない可能性があります。

  1. 参考情報 (あれば)
  • 対象 PR: https://github.com/rails/rails/pull/56692
  • Rails のエラーページに関係するクラス:
    • ActionDispatch::DebugExceptions
    • ActionDispatch::ShowExceptions
  • 関連テンプレートの実ファイル:
    • actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
    • actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb

#56696 Add documentation for foreign key options to add_reference [ci skip]

マージ日: 2026/1/30 | 作成者: @wakairo

  1. 概要 (1-2文で)
    add_reference のドキュメントに、foreign_key: オプションとして add_foreign_key と同じオプションを渡せることを明示するリンクを追加した PR です。実装挙動の変更はなく、API ドキュメントだけを改善する変更です。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象: ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference のドキュメントコメント
  • 変更点: foreign_key: オプションの説明に、SchemaStatements#add_foreign_key へのリンクを追記

これにより、add_referenceforeign_key: に指定できるオプションが、add_foreign_key と同じであることがドキュメント上も分かりやすくなりました。
既にテストでカバーされている以下のようなオプションが、add_reference 経由でも利用可能であることを明示する狙いです:

  • :deferrable
  • :on_delete
  • :on_update
  • (その他 add_foreign_key がサポートするオプション)

想定される利用例

ruby
# マイグレーション例
class AddUserToPosts < ActiveRecord::Migration[7.2]
  def change
    add_reference :posts, :user,
                  foreign_key: {
                    on_delete: :cascade,
                    on_update: :cascade,
                    deferrable: :initially_deferred
                  }
  end
end

従来からこのような指定は技術的には可能でしたが、公式ドキュメントには明記されていなかったため見つけづらかった、という問題を解消しています。


  1. 影響範囲・注意点
  • 実装コードの変更はなく、ドキュメントのみの変更です。
  • そのため、既存アプリケーションの挙動には影響しません。
  • これまで暗黙的に使っていた foreign_key: の詳細オプションが、今後は公式に案内されるようになるため、マイグレーション記述の設計(削除・更新時の動作や deferrable 制約など)を見直すきっかけにはなり得ます。
  • 逆に、「add_reference では foreign_key: true/false しか指定できない」と誤解していた場合、add_foreign_key と同等の柔軟な指定ができることを前提に設計を変えられるようになります。

  1. 参考情報 (あれば)
  • 対象メソッド:
    • ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference
    • ActiveRecord::ConnectionAdapters::SchemaStatements#add_foreign_key
  • 関連ドキュメント:
    • TableDefinition#references は、すでに add_reference を参照する形になっており、本 PR によってそこから add_foreign_key まで辿れるようになったため、オプション仕様のドキュメント導線が整理されました。

#56694 Update typemap for timezone during type_casted_binds

マージ日: 2026/1/29 | 作成者: @matthewd

  1. 概要 (1-2文で)
    PostgreSQL アダプタで、バインド変数を type cast するタイミングで timezone 用 typemap を確実に更新するようにした PRです。
    現時点の挙動は変えず、今後の timezone/型関連の変更に備えて、責務と呼び出し位置を整理しています。

  1. 変更内容の詳細

※実際の差分は要約に基づく推測を含みますが、Rails の既存実装と PR 説明から技術的に妥当な範囲で補っています。

2-1. 変更のポイント

  • PostgreSQL アダプタの「timezone に依存する typemap 更新処理」を、

    • これまでとは別の場所(type_casted_binds 呼び出しタイミング)
    • つまり「実際に outgoing binds を type cast する直前」 に移動・紐づけました。
  • 具体的には:

    • activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
      「bind の type casting 時に timezone typemap を更新する」ための処理が追加。
    • activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb からは
      旧来の呼び出し位置にあった呼び出し(1行)が削除され、責務が quoting.rb 側に移管された形です。
  • activerecord/test/cases/base_test.rb に 14 行分のテストが追加され、

    • timezone が変わった時でも
    • outgoing bind の type casting のタイミングで
    • 適切な typemap が使われていること を保証しています。

2-2. どのように動くようになったか(概念的イメージ)

Rails の PostgreSQL アダプタでは、Ruby のオブジェクト(Time, DateTime など)を DB に送る際に、
「DB が理解できるフォーマット」に変換するための typemap を使っています。

この PR のポイントは次の通りです:

  • いままでは

    • timezone 設定が変わった際などに、どこか別のタイミングで typemap を更新していた。
    • 実際に bind を type cast する時点で typemap が最新である保証が、コード構造上やや分かりづらかった。
  • これからは

    • type_casted_binds を実行する「まさにそのタイミング」で、
    • 「今の timezone に基づいた typemap がセットされている」ことを保証するようにした。
    • これにより、timezone に依存する Time / DateTime / timestamptz などの値を変換するときに、
      常に正しい typemap が使われることがコード上も明確になる。

PR 説明にある通り:

Typecasting of outgoing binds is the moment we need to have the correct typemap in place, so let's put the call there.

という設計の整理です。

2-3. 挙動は変わらない

作者のコメント:

This doesn't change any existing behaviour; it just sets up a clearer path ahead of other changes I'm planning to make here.

  • 既存のアプリケーションから見て「結果が変わる」ことはないように実装されています。
  • 実質的には「typemap 更新処理の呼び出し位置を、より適切な場所に移しただけ」で、
    将来のリファクタリングや機能追加のための下準備、という位置づけです。

  1. 影響範囲・注意点

3-1. 影響範囲

  • 対象:PostgreSQL を使う Rails アプリケーションの ActiveRecordpostgresql アダプタ)。
  • 主な対象機能:
    • where, insert, update, delete などで使われる バインド変数付きクエリの実行
    • 特に、Time / DateTime / ActiveSupport::TimeWithZone など「timezone の影響を受ける型」の bind

ただし、PR の意図通りであれば「実行結果や SQL の中身」は変わりません。

3-2. アプリ側で気にするべき点

  • この PR 単体では互換性上の注意点はほぼないと考えてよいです。
  • 万が一、PostgreSQL アダプタを monkey patch している場合は、以下を確認すると安全です:
    • ActiveRecord::ConnectionAdapters::PostgreSQLAdapter まわりで
      • timezone/typemap 更新処理、
      • type_casted_binds や quoting 関連メソッド を上書きしていないか。
  • 将来的に、timezone/型システムまわりのリファクタリングや拡張が入る可能性が高いので、
    • Rails 本体の PG アダプタ内部に依存した独自拡張をしている場合は、
    • バージョンアップ時に changelog / PR を追うと安心です。

  1. 参考情報 (あれば)
  • PR: https://github.com/rails/rails/pull/56694
  • 関連しそうな既存の仕組み:
    • ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#configure_connection
    • ActiveRecord::ConnectionAdapters::PostgreSQL::OID 周り(timestamptz, timestamp など)
    • ActiveSupport::TimeZone, Time.zone= などの timezone 設定

この PR は「挙動を変えずに内部構造を整理するタイプ」の変更で、
今後の timezone / typemap 周りの改善(例: より明確な timestamptz サポート強化など)に向けた前段階と考えられます。


#56693 Combine duplicate if respond_to?(:action_view)

マージ日: 2026/1/29 | 作成者: @r7kamura

  1. 概要 (1-2文で)
    Rails の Rails::Application::Configuration 周辺で、if respond_to?(:action_view) が重複していた箇所をまとめる小規模なリファクタリングです。挙動は変えずに、コードの読みやすさと自然さを改善しています。

  1. 変更内容の詳細
  • 対象ファイル: railties/lib/rails/application/configuration.rb
  • 行数: 追加 0 行 / 削除 3 行
  • 内容: 「respond_to?(:action_view) を複数回チェックしていた不自然なコード」を整理し、重複する条件分岐を1つにまとめる形に修正しています。

PR 説明から読み取れる意図としては:

  • load_defaults 8.0 から 8.1 へ変更するためにコード周りを読んでいたところ、
  • if respond_to?(:action_view) が近い位置で重複しており、不自然・冗長だったため、
  • その条件分岐を統合してスッキリさせた、というリファクタリングです。

実際の差分は -3 行のみで、「同じ条件を2 回書いていた」ようなケースを 1 回にする程度と考えられます。例えばイメージとしては、以下のような重複:

ruby
if respond_to?(:action_view)
  # 何らかの設定
end

# すぐ下で再び
if respond_to?(:action_view)
  # 別の設定
end

を、次のようにまとめた形に近い処理になっていると考えられます:

ruby
if respond_to?(:action_view)
  # ここに action_view 関連の設定をまとめる
end

実際の削除行数から見て、処理そのものを削除したのではなく、条件の記述位置やブロック構造を整理した程度の修正です。


  1. 影響範囲・注意点
  • 機能的な変更:

    • 挙動変更は意図されておらず、純粋なリファクタリングです。
    • respond_to?(:action_view) の条件下でしか動かない設定である点は変わっていません。
  • 影響範囲:

    • Rails::Application::Configuration のうち、Action View 関連の設定が行われる部分のみです。
    • config.load_defaults 8.0 / 8.1 周辺のコードパス上にありますが、条件分岐を統合しただけなので、特定バージョンのデフォルト設定挙動が変わる可能性は低いです。
  • 注意点(アップグレード時など):

    • Rails 8.1 系(予定)に追随している場合でも、この PR 単体で API や設定項目の互換性問題が起きる可能性はほぼありません。
    • もし Rails::Application::Configuration を独自にモンキーパッチしていたり、respond_to?(:action_view) の有無を前提に動的に振る舞いを変えるようなメタプログラミングをしている場合は、差分を一度確認すると安心です(ただし、通常のアプリケーションではまず関係しません)。

  1. 参考情報 (あれば)

Rails 8.1 への移行や config.load_defaults 8.1 対応時に周辺コードを読む場合、「respond_to?(:action_view) は一度だけチェックされる」ように整理された、という程度の認識を持っておけば十分です。


#56687 Remove unused delegate loading from MemCacheStore

マージ日: 2026/1/27 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    MemCacheStore 内で使われていない require "delegate" を削除し、不要な依存を取り除いた PR です。機能的な挙動変更はなく、コードのクリーンアップに該当します。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル: activesupport/lib/active_support/cache/mem_cache_store.rb
  • 変更内容: 1 行削除(require "delegate" の削除)のみ

削除された行(イメージ):

ruby
# 変更前
require "delegate"
require "active_support/cache/store"
# ...

# 変更後
require "active_support/cache/store"
# ...

背景:

  • もともと require "delegate" は、DelegateClass を使う DupLocalStore のために追加されていました(コミット 5d1e888)。
  • その後、キャッシュフォーマットの非推奨バージョン 6.1 のサポート削除に伴い、DupLocalStoreDelegateClass の利用自体が削除されました(コミット 38bfbcfbeacf461cafc4ef816cd5552696da2352)。
  • しかし require "delegate" だけが残っており、今回の PR でそれを整理した、という経緯です。

実質的には「もう使っていない標準ライブラリを require していたので消した」だけの変更です。


  1. 影響範囲・注意点
  • 機能面の影響:

    • MemCacheStore の動作仕様・API には一切変更がありません。
    • 削除されたのは未使用の require だけなので、通常のアプリケーション利用では挙動は完全に従来どおりです。
  • 互換性:

    • 破壊的変更はありません。
    • Rails の他の部分で delegate に依存している箇所は、必要に応じてそれぞれが require "delegate" している(または不要)ため、ここから require "delegate" を消しても問題ありません。
    • もし「mem_cache_store.rbdelegate を読み込んでくれていること」をアプリ側で暗黙的にアテにしていたケースがあれば、極めて例外的に影響し得ますが、通常そのような依存の仕方は推奨されません。
  • パフォーマンス・ロード時間:

    • delegate は標準ライブラリとはいえ I/O を伴うため、ほんのわずかですが起動時の require コストが減ります。
    • 大規模アプリやツール群における「不要 require 削減」による総合的な起動時間・メモリ削減の一環と捉えられます。

  1. 参考情報 (あれば)
  • この PR の文脈となる過去コミット:
    • require "delegate" が追加されたコミット: 5d1e888
    • DelegateClass を使っていた DupLocalStore および cache format 6.1 のサポート削除: 38bfbcfbeacf461cafc4ef816cd5552696da2352
  • 関連概念:
    • DelegateClass(標準ライブラリ delegate): 既存クラスをラップしてメソッドを委譲するためのユーティリティ。
    • Rails 内では、一時的なラップ(例えば古いフォーマットや特殊なローカルストアの実装)で使われることがありますが、本 PR により MemCacheStore ではもう利用されていません。

#56686 [Changelog] Fix overlapping acronyms order dependency in underscore#56679

マージ日: 2026/1/27 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Active Support の underscore における「重なり合う略語(acronym)」の展開順序依存バグを修正したことを、CHANGELOG に追記する PR です。
    コード本体には手を入れず、既にマージ済みの修正内容をドキュメントとして明示しただけの変更です。

  1. 変更内容の詳細
  • 変更ファイルは activesupport/CHANGELOG.md のみで、Active Support に関する変更点として以下の内容(要旨)が追記されています:
    • underscore メソッドで、config/initializers/inflections.rb などに登録された複数の略語が「互いに部分的に重なっている」場合(例: APIAP のような関係)、登録順によって underscore の結果が変わってしまう問題があった。
    • この「略語の重なり」による順序依存バグが修正されたことが CHANGELOG に記載された。

実際のコード修正自体は前のコミット(説明文にあるリンク: 38e8df6a5a3...)で行われており、この PR はその修正内容を CHANGELOG に反映させるだけのものです。

「重なり合う略語」のイメージ例(※これは概念説明用で、PR本文にはサンプルは出ていません):

ruby
# 例: Inflector に略語を登録
ActiveSupport::Inflector.inflections do |inflect|
  inflect.acronym "API"
  inflect.acronym "AP"
end

"APIClient".underscore
# 修正前: 登録順によって "api_client" になったり "a_p_i_client" のように
# おかしな分割結果になったりする可能性があった
#
# 修正後: 「重なり」を考慮した安定した処理順序で展開される
# (登録順に結果が左右されない)

上述のような挙動の不安定さが解消された、という事実が CHANGELOG に明文化されています。


  1. 影響範囲・注意点
  • この PR 自体はドキュメント(CHANGELOG)のみの変更なので、挙動を新たに変えるものではありません。
  • ただし、元になっている修正(以前のコミット)によって:
    • ActiveSupport::Inflector.acronym を複数定義しているアプリで、
    • それらの略語が互いに部分一致する(HTMLHT など)場合、
    • underscore の結果が「これまでのバージョン」と変わる可能性があります。
  • 特に以下のようなケースに該当するアプリは、テストで underscore の結果を一度確認しておくと安心です:
    • 略語を多く登録している API / マイクロサービス
    • モデル名・クラス名にカスタム略語を多用しているドメイン(FinTech、IoT、通信など)

  1. 参考情報 (あれば)

#56282 Fix #56232: Clean output directory when generating guides to remove stale output files and add guide generation tests

マージ日: 2026/1/27 | 作成者: @harsh183

  1. 概要 (1-2文で)
    Rails ガイド生成時に、出力ディレクトリ内に古い HTML ファイルなどが残り続ける問題を修正し、新しい生成前に出力ディレクトリをクリーンアップするようにしました。あわせてガイド生成処理に対するテストが追加され、挙動が自動テストで担保されるようになっています。

  1. 変更内容の詳細

問題点

Issue #56232 で報告されていた通り、ガイド(guides)を再生成しても、

  • 以前存在していたが、現在は削除された/リネームされたガイドの HTML
  • その他、もはや生成されない古い出力ファイル

output ディレクトリ内に残り続け、結果として:

  • 古い URL がそのままアクセス可能
  • 検索エンジンにインデックスされ続ける

という問題がありました。

対応内容

a. ガイド生成時に出力ディレクトリをクリーンにする

guides/rails_guides/generator.rb のガイド生成処理で、新規生成前に出力ディレクトリを削除(もしくは中身をクリーンアップ)してから、改めてファイルを書き出すように変更されています。

概念的には、以下のような処理が入ったと考えればよいです(擬似コード):

ruby
# ガイド生成前
FileUtils.rm_rf(output_dir)      # 既存の出力ディレクトリを削除
FileUtils.mkdir_p(output_dir)    # 必要であれば作り直す

# その後に各ガイドを HTML 等に変換して output_dir に書き出す
generate_all_guides(output_dir)

これにより、古いガイドが削除されても、次回の生成時に古い HTML が残り続けることはなくなります。

b. ガイド生成テストの追加

guides/test/generator_test.rb が新規追加され(+85行)、ガイド生成ロジックの挙動をテストするようになりました。主なポイントとしては:

  • 出力ディレクトリを事前に汚しておき(ダミーファイルを置くなど)、
    ガイド生成後にそれらが削除されていることを確認するテスト
  • ガイド生成後に期待されるファイルが正しく作成されることの確認

のような形で、「生成前にディレクトリがクリーンアップされること」と「期待どおりのファイルが生成されること」を自動テストで保証しています。

c. CHANGELOG の更新

guides/CHANGELOG.md に、この挙動変更がガイド生成の振る舞い変更として記載されています。
(ガイド生成ツールを使っている人向けの情報として、「出力ディレクトリは毎回クリーンアップされる」という仕様が明文化された形です。)


  1. 影響範囲・注意点
  • 影響対象:

    • Rails のガイド生成ツール(guides ディレクトリ配下の仕組み)を使っている人・CI などでガイドの静的 HTML を生成している人。
    • rails/rails リポジトリの公式ガイド(edgeguides / api.rubyonrails.org など)の生成フロー。
  • 変更点の性質:

    • これまで「出力ディレクトリに手で置いたファイル」や「過去バージョンの生成物」が残ってしまう挙動から、「毎回クリーンなディレクトリに対してガイドを生成する」挙動に変わっています。
  • 注意点:

    • 出力ディレクトリ内に手動で置いていた独自ファイルがある場合、ガイド生成を走らせると削除される可能性があります。
      • もし独自の静的ファイル(例: カスタム HTML, 画像, スクリプト)をガイド出力と同じディレクトリに混在させていた場合は、
        • 別ディレクトリに移す
        • 生成処理の中でコピーするステップを追加する
          などの対応が必要になります。
    • CI / デプロイフローで「出力ディレクトリを前提に何かを差分比較している」ような場合も、クリーンアップによる挙動変化の影響がないか確認が必要です。

  1. 参考情報 (あれば)

#56668 chore: Update outdated GitHub Actions versions

マージ日: 2026/1/25 | 作成者: @pgoslatara

  1. 概要 (1-2文で)
    このPRは、Railsリポジトリ内で使用している複数のGitHub Actionsを最新メジャーバージョンに更新するメンテナンス目的の変更です。アプリケーションコードやテストコードには手を入れず、CI/運用ワークフローの信頼性と追従性を高めるための更新になります。

  1. 変更内容の詳細

対象は .github/workflows/ 配下の4つのWorkflowファイルで、それぞれで利用している公式Actionsのバージョンタグだけを更新しています。

2-1. releaseワークフロー: actions/setup-node v4 → v6

yaml
# 変更前
- uses: actions/setup-node@v4

# 変更後
- uses: actions/setup-node@v6

actions/setup-node は、GitHub Actions上でNode.jsのインストール・キャッシュ設定などを行う公式Actionです。
Rails本体であっても、ドキュメント生成・フロントエンド関連ツール・パッケージ管理(yarn / npm)などでNode.jsが必要なジョブがあるため、その環境構築部分が最新化されます。

v6 では、より新しいNode.jsバージョンへの対応やパフォーマンス・セキュリティ改善が含まれている可能性が高く、将来的なNodeバージョンアップ時の互換性確保にもつながります。


2-2. staleワークフロー: actions/stale v9 → v10

対象ファイル:

  • .github/workflows/stale.yml
  • .github/workflows/more-info-needed.yml
yaml
# 変更前
- uses: actions/stale@v9

# 変更後
- uses: actions/stale@v10

actions/stale は、一定期間アクティビティのないIssue/PRに stale ラベルを付与したり、自動クローズしたりするためのActionです。

  • stale.yml: 一般的な「古くなったIssue/PR」を自動管理
  • more-info-needed.yml: 追加情報待ちのIssueに対して、情報が来ないものを自動的に整理

いずれも同じActionを利用しており、そのバージョンを一括でv10に更新しています。設定内容(ラベル名、日数、コメント文など)は変えていないため、振る舞いは基本的に同じで、内部実装や改善点だけが新しくなる形です。


2-3. ラベラー: actions/labeler v5 → v6

対象ファイル:

  • .github/workflows/labeler.yml
yaml
# 変更前
- uses: actions/labeler@v5

# 変更後
- uses: actions/labeler@v6

actions/labeler は、PR内で変更されたファイルパスに応じてラベルを自動付与するActionです。
例: activerecord/** を変更したら activerecord ラベル、guides/** を変更したら documentation ラベル、など。

今回のPRでは、Actionのバージョンタグのみをv6へ更新しており、ラベリングルール(labeler.yml 内の設定)自体には変更がありません。


  1. 影響範囲・注意点
  • 影響範囲

    • アプリケーションコードやRailsの挙動には一切影響せず、「GitHub上でPRやIssueをどう自動管理するか」というメンテナンス運用部分のみが対象です。
    • 実際に影響が出るのは、以下のタイミングで実行されるGitHub Actionsジョブ:
      • リリース関連のWorkflowでNode.js環境をセットアップするとき
      • 一定期間動きのないIssue/PRをstale扱いにするとき
      • PR作成/更新時に自動でラベル付与するとき
  • 考えられる注意点・リスク

    • メジャーバージョンアップのため、以下のような潜在的な変更点に注意が必要です(今回のPRでは特に追記されていないため、該当Actionのリリースノートを参照する前提になります)。

      • actions/setup-node@v6
        • 非推奨オプションの削除・挙動変更
        • デフォルトNodeバージョンやキャッシュ戦略の変更
      • actions/stale@v10
        • ラベル付与/削除のデフォルト挙動の変更
        • メッセージテンプレートや日数設定の扱いの微調整
      • actions/labeler@v6
        • 設定ファイルフォーマットの警告強化や、マッチングロジックの改善
    • 実務上は、マージ後しばらくは:

      • staleラベルが意図しないIssue/PRに付与・削除されていないか
      • ラベル自動付与がこれまで通り機能しているか
      • release系Workflowがエラーなく完走しているか
        をモニタリングすると安全です。

  1. 参考情報 (あれば)

これらのリポジトリのリリースノート / CHANGELOG を確認すると、v4→v6, v9→v10, v5→v6 で導入された詳細な変更点(非推奨オプションの削除や新機能など)を把握できます。Rails本体の運用方針としては、こうした公式Actionsのメジャーバージョンに定期的に追従しておくことで、中長期的なメンテコストとトラブルシュートの負荷を減らす狙いがあると考えられます。


#56679 Fix overlapping acronyms order dependency in underscore

マージ日: 2026/1/25 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Rails の ActiveSupport::Inflector.underscore が、重なり合う略語(例: USDUSDC)定義時に登録順によって結果が変わってしまう問題を修正した PR です。略語を正規表現に組み込む際に「長い略語を優先的にマッチさせる」ようにし、順序依存をなくしています。

  1. 変更内容の詳細

何が問題だったか

underscore は、ActiveSupport::Inflector.inflections に登録された略語 (acronyms) を考慮して CamelCase を snake_case に変換します。

ruby
ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.acronym "USD"
  inflect.acronym "USDC"
end

このように「前方一致で重なる」略語が登録されている場合、内部で使われる正規表現はおおよそ次のような形になります(イメージ):

ruby
/(?:USD|USDC)/    # 実際にはもう少し複雑

Ruby の正規表現はオルタネーション | を左から右に評価するため、

  • 略語が ["USD", "USDC"] の順で登録されると /USD|USDC/
  • 略語が ["USDC", "USD"] の順で登録されると /USDC|USD/

となり、同じ入力文字列 "USDCurrency" の処理結果が「略語の登録順」に依存して変わる、という問題がありました。
本来は、文字列的により長い USDC を優先的にマッチしてから処理すべきです。

どう直したか

PR では、略語を正規表現に組み込む前に「長い順にソート」することで、常に長い略語が先に評価されるようにしました。

イメージ的には、これまで:

ruby
acronyms = ["USD", "USDC"] # 登録順そのまま
regex = Regexp.union(acronyms) # => /USD|USDC/

だったものを、今回の変更で:

ruby
acronyms = ["USD", "USDC"]
sorted = acronyms.sort_by { |a| -a.length } # => ["USDC", "USD"]
regex = Regexp.union(sorted)                # => /USDC|USD/

のように、常に「長い方が先に来る」正規表現にしています。
これにより、入力 "USDCurrency" に対しては必ず USDC がマッチし、それをもとに underscore が snake_case を生成します。

テストの追加

activesupport/test/inflector_test.rb にテストが追加されており、以下のような状況でも結果が登録順に依存しないことを確認しています(テストコードのイメージ):

ruby
ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.acronym "USD"
  inflect.acronym "USDC"
end

assert_equal "usdc_transaction", "USDCTransaction".underscore
assert_equal "usd_currency", "USDCurrency".underscore

あるいは順序を入れ替えて登録しても、同じ結果が得られることを確認するテストになっています。


  1. 影響範囲・注意点
  • 影響範囲:
    • ActiveSupport::Inflector.underscore の挙動のうち、「重なり合う略語 (overlapping acronyms)」が存在するケースのみ。
    • 略語を定義していない、または互いに前方一致しない略語のみを使っているケースには影響しません。
  • 期待される変化:
    • これまで「略語の登録順」によって結果が変わっていたアプリケーションでは、挙動が安定します。
    • もし「たまたま短い略語が先にマッチすること」を前提にワークアラウンドしていた場合、その挙動は変わりますが、その前提自体がバグ依存であり、より直感的かつ妥当な挙動に修正されたと言えます。
  • パフォーマンス:
    • 略語リストを長さでソートする処理が増えますが、通常は略語の数が少ないためオーバーヘッドは非常に小さいと考えられます。
  • 互換性:
    • CHANGELOG にはまだ追記されていませんが、実質的には「バグ修正」として扱うべきレベルの挙動変更です。

  1. 参考情報 (あれば)

#56678 Disable console query cache by default

マージ日: 2026/1/25 | 作成者: @camallen

  1. 概要 (1-2文で)
    Railsコンソールで、デフォルトでは有効になってしまっていたクエリキャッシュを「無効」に戻す変更です。必要な場合のみ --query-cache (短縮: -q) オプションで明示的に有効化できるようになります。

  1. 変更内容の詳細

背景

  • 以前のPR(#56297)の影響で、Railsコンソール起動時に Active Record のクエリキャッシュがデフォルトで有効になっていました。
  • その結果、コンソールで同じクエリを繰り返し実行しても、DB を再度叩かずキャッシュ結果が返ってくるケースがあり、デバッグや動作確認の際に「実際のDB問い合わせ」と挙動が異なってしまう問題がありました(issue #56473)。

このPRでの仕様変更

1) デフォルトではクエリキャッシュを「使わない」ように変更

  • コンソールセッション開始時に、明示的にクエリキャッシュを有効化しない限り、クエリキャッシュは無効になります。
  • つまり、コンソールでの挙動は「本番/開発環境の通常リクエストに近い」というよりも、「毎回DBに問い合わせる」ことを前提としたデバッグ向きの挙動になります。

2) --query-cache / -q オプションの追加(opt-in)

  • クエリキャッシュを使いたい場合は、コンソール起動時にオプションを指定します。
bash
# クエリキャッシュを有効にして Rails console を起動
bin/rails console --query-cache
# または短縮形
bin/rails console -q
  • オプションなし:
bash
bin/rails console
# => クエリキャッシュは無効(これが新しいデフォルト)

3) --skip-executor との関係

  • 説明文にある通り、「--skip-executor を使っているときは -q の効果はない」と明示されています。
    • --skip-executor は、Rails の標準的な Executor(スレッドローカルの状態管理やミドルウェア相当の仕組み)を使わずにコンソールを動かすオプションです。
    • クエリキャッシュも通常は Executor のライフサイクルに紐づいて管理されるため、Executor をスキップするとクエリキャッシュの制御も事実上できなくなる、という設計上の事情があります。
  • したがって:
bash
bin/rails console --skip-executor -q
# => -q は無視され、クエリキャッシュは有効にならない

4) 実装箇所

  • 主な変更ファイル:
    • railties/lib/rails/commands/console/console_command.rb
      • コンソールコマンドのオプション定義と、クエリキャッシュの有効/無効制御ロジックを追加。
    • railties/test/application/console_test.rb
      • クエリキャッシュのデフォルトオフと --query-cache 有効時の挙動に関するテスト追加。
    • railties/CHANGELOG.md
      • コンソールのクエリキャッシュ挙動変更についてのエントリを追加。

(PR本文にはコード断片がありませんが、構成からすると Rails::Console 実行前後で ActiveRecord::Base.connection.enable_query_cache! / disable_query_cache! 相当をオプションに応じて切り替える実装になっていると考えられます。)


  1. 影響範囲・注意点
  • 開発者が Rails console を使うときの挙動が変わる

    • これまで(#56297 マージ後)、コンソールで同じクエリを何度実行しても2回目以降はキャッシュヒットしていたケースが、今回の変更以降は毎回DBに問い合わせるようになります。

    • 例:

      ruby
      # 以前(キャッシュON):
      User.find(1)  # => DB問い合わせ
      User.find(1)  # => クエリキャッシュから取得(ログにSQLが出ない)
      
      # 今回のPR後(デフォルトOFF):
      User.find(1)  # => DB問い合わせ
      User.find(1)  # => もう一度DB問い合わせ(SQLが出る)
  • パフォーマンステストやキャッシュ動作を確認したいコンソールセッションは -q が必要

    • 「コンソールからの一連の処理が、クエリキャッシュを前提としたアプリケーション本番挙動に近いかを見たい」場合は、明示的に:

      bash
      bin/rails console -q

      と起動する必要があります。

  • --skip-executor を常用している場合は -q を指定しても意味がない

    • 既にツールやスクリプトなどで bin/rails console --skip-executor を使っている場合、今回の PR で追加された --query-cache は効かないので、クエリキャッシュを伴う挙動検証には向きません。
    • その場合は --skip-executor を外して -q を付けるか、別途アプリケーションコード/テスト環境で検証する必要があります。
  • テストとドキュメントが更新済み

    • この挙動はテストでカバーされており、railties の CHANGELOG にも明示されているため、Rails 公式としてサポートされる仕様変更です。

  1. 参考情報 (あれば)

#56670 [ci skip] Fix guides for db:prepare

マージ日: 2026/1/25 | 作成者: @schmijos

  1. 概要 (1-2文で)
    このPRは、rails db:prepare の挙動に関するRailsガイドの記述を、実際の実装どおり「マイグレーション実行+スキーマダンプを行う」ことが明確に伝わるよう修正したドキュメント更新です。コード本体の挙動は変わっておらず、ガイドの説明だけが実装に合わせて整合性を取られています。

  1. 変更内容の詳細
  • 対象ファイル: guides/source/active_record_migrations.md
  • 行数ベース: 6行追加 / 7行削除(記述の言い換え・修正レベル)

主なポイントは以下です。

db:prepare の説明を実装に合わせて修正

Active Record のタスク実装(ActiveRecord::Tasks::DatabaseTasks#prepare 付近)では、db:prepare は以下のような処理を行います(該当実装へのリンクがPR説明に記載):

ruby
# おおよその処理イメージ
def prepare
  migrate
  dump_schema_if_needed
end

このPRでは、ガイド中の db:prepare に関する説明が、上記の実装内容とずれていたため、

  • 「マイグレーションを実行するかどうか」
  • 「スキーマダンプ(schema.rb / structure.sql の出力)を行うかどうか」

といった点についての表現を「明示的に migrate & dump schema を行う」とわかるように修正しています。

それまでのガイドには、例えば以下のような問題がある表現だった可能性があります(ニュアンス例):

  • db:prepare は「必要であればマイグレーションを実行する」程度の曖昧な説明
  • スキーマダンプについて触れていない、もしくは挙動と一致しない説明

それを、

  • db:migrate を実行する
  • その後、スキーマファイルをダンプする(db:schema:dump あるいは db:structure:dump 相当)

といった形で正確に反映した内容に修正しています。


  1. 影響範囲・注意点
  • 影響範囲:

    • コードは変更されていないため、Railsの実際の挙動には一切影響ありません。
    • Active Record Migrations ガイド(ドキュメント)を参照して db:prepare の挙動を理解している開発者・チームに対する「認識の修正」が主な影響です。
  • 注意点:

    • CI やデプロイスクリプトで rails db:prepare を利用している場合、「マイグレーション実行だけでなく、スキーマダンプも毎回走る」ことを前提にすべきである、という点がガイド上もより明示されます。
    • スキーマダンプの有無を前提にしたフロー(例: schema.rb をコミットしている運用、structure.sql を前提にしたDBツール連携など)で、db:prepare を使うか db:migrate / db:schema:load を個別に使うかを再検討する材料になります。
    • ドキュメントと実装が一致したため、今後 db:prepare の挙動をカスタムRakeタスクやスクリプトで前提にする際に、誤った理解に基づくトラブルが減ります。

  1. 参考情報 (あれば)

#56672 Add changelog for 6f9cbce21d8ec2de86c37b5a37073bac6d5f1d83 to Action Cable and Action Text

マージ日: 2026/1/24 | 作成者: @zzak

  1. 概要 (1-2文で)
    このPRは、既に他のコンポーネント(Railties)にのみ追加されていた変更内容(コミット: 6f9cbce21d8e...)について、Action Cable と Action Text 向けのCHANGELOG記載を追加し、フレームワーク全体で変更履歴の整合性を取るものです。コードの挙動自体は変えず、ドキュメント(CHANGELOG)のみを更新しています。

  1. 変更内容の詳細
  • 対象:
    • actioncable/CHANGELOG.md
    • actiontext/CHANGELOG.md
  • 内容:
    • コミット 6f9cbce21d8ec2de86c37b5a37073bac6d5f1d83 で導入された変更が、Rails本体(Railties)のCHANGELOGには記載されていたが、Action Cable と Action Text のCHANGELOGには反映されていなかったため、それぞれに追記しています。
    • 実際の差分はそれぞれ4〜5行程度で、主に以下のような情報が追加されていると考えられます:
      • どの機能・挙動が変更/追加されたか
      • 対応するPR/コミットのハッシュ
      • 必要に応じて「Breaking Change」や「Deprecation」等のラベル

このPR自体には Ruby コードや設定ファイルの変更はなく、アプリケーションの実行パスには一切影響しません。
そのため、サンプルコードレベルでの差分・対応は不要です。


  1. 影響範囲・注意点
  • 影響範囲:

    • 実行時挙動: 影響なし
    • ビルド・テスト: 影響なし
    • ドキュメント/リリースノート: 影響あり(Action Cable / Action Text のCHANGELOGが正しく追従)
  • 開発者視点でのポイント:

    • Rails 7.x/8.x など該当バージョンの Action Cable / Action Text の変更点を追跡する際に、これまで Railties のCHANGELOGにしか書かれていなかった情報が、各コンポーネントのCHANGELOGからも確認できるようになります。
    • すでに 6f9cbce21d8e... の変更を利用している・検証している場合でも、このPRによる挙動の変化はありません。
      あくまで「変更は前からあったが、ログが不足していた」状態を是正するものです。
  • 注意点:

    • 「CHANGELOGに新しい記述がある=今回のPRで新たに挙動が変わった」というわけではない点に留意してください。
      実際の機能変更が行われたのは元のコミット/PR(#56636 側)です。
    • バージョンアップの影響調査やリリースノート作成時は、今回追加された記述とコミット 6f9cbce21d8e... / PR #56636 の内容をセットで確認すると把握しやすくなります。

  1. 参考情報 (あれば)
  • 元となった変更:

    • PR #56636
    • コミット: 6f9cbce21d8ec2de86c37b5a37073bac6d5f1d83
      (具体的な機能変更・API変更の内容は、このコミット/PR側を参照してください)
  • 関連ファイル:

    • actioncable/CHANGELOG.md
    • actiontext/CHANGELOG.md
    • railties/CHANGELOG.md(すでに該当変更が記載済み)

このPRは、ドキュメントの一貫性・完全性を高めるための「後追いのCHANGELOG整備」として理解するとよいです。


#56666 Skip unique index lookup for insert_all! since it doesn't need conflict target

マージ日: 2026/1/23 | 作成者: @kirs

  1. 概要 (1-2文で)
    insert_all! が常にユニークインデックスを探しに行っていた挙動を修正し、実際には ON CONFLICT を使わないケースではユニークインデックスを必須にしないようにした PR です。これにより、特に複合主キーを持つテーブルで model.primary_key とスキーマ上の主キーがずれている場合に発生していた不要な例外が解消されます。

  1. 変更内容の詳細

背景

  • insert_all! は内部的に on_duplicate: :raise を使っています。
  • on_duplicate: :raise は「重複が起きたら例外を投げる」方針であり、DB 的には「単なる INSERT」を発行するだけで、ON CONFLICT 句は一切使いません。
  • それにもかかわらず、これまでは insert_all! 呼び出し時にも find_unique_index_for が常に実行されており、衝突ターゲットを決めるためのユニークインデックスを必須としていました。

その結果、以下のようなケースで問題が発生していました:

ruby
# モデル側: 単一主キーを指定
class Order < ApplicationRecord
  self.primary_key = :id
end

# DB 側: 複合主キー (例: shop_id + id)
create_table :orders, primary_key: [:shop_id, :id] do |t|
  t.bigint :shop_id
  t.bigint :id
  # ...
end

このようなとき、insert_all! は ON CONFLICT を使わないにも関わらず、
「ユニークインデックス(あるいは主キー定義)が期待通りに取れない」としてエラーになるケースがありました。

具体的な変更点

  • activerecord/lib/active_record/insert_all.rb のロジックを 1 行変更
    ざっくりいうと:

    ruby
    # 変更前(イメージ)
    unique_index = find_unique_index_for(...)

    を、

    ruby
    # 変更後(イメージ)
    unique_index = find_unique_index_for(...) if on_duplicate_requires_conflict_target?

    のように、「ON CONFLICT の衝突ターゲットが必要な場合(:skip, :update)のみ find_unique_index_for を実行する」ように条件付きにした形です。

  • テスト (activerecord/test/cases/insert_all_test.rb) では以下を追加:

    • insert_all! が複合主キーを持つテーブルでも、ON CONFLICT を必要としない限りユニークインデックス探索を要求しないこと
    • その結果として、モデルの primary_key とスキーマ上の primary key 定義がずれていても insert_all! が動作すること

ふるまいの整理 (insert_all / insert_all! / upsert_all)

  • insert_all!

    • 内部: on_duplicate: :raise
    • 実際の SQL: 単純な INSERT のみ(ON CONFLICT なし)
    • 今回の変更後: ユニークインデックスは不要(find_unique_index_for しない)
  • insert_all

    • 内部: on_duplicate: :skip
    • 実際の SQL: INSERT ... ON CONFLICT (...) DO NOTHING
    • 衝突ターゲットが必要なので、これまで通りユニークインデックス/主キーの情報が必要
  • upsert_all

    • 内部: on_duplicate: :update
    • SQL: INSERT ... ON CONFLICT (...) DO UPDATE SET ...
    • 同様に衝突ターゲットが必要なため、これまで通りユニークインデックスが必要

  1. 影響範囲・注意点
  • 影響する主なケース

    • 複合主キーを持つテーブルで、
    • モデル側で self.primary_key を単一カラムにしているなど、モデルの主キー情報と DB スキーマの主キー/ユニークインデックス定義が一致していないケース
    • そのようなモデルに対して insert_all! を使っていたときに発生していた「ユニークインデックスが見つからない」類のエラーが解消される可能性があります。
  • 変わらない部分

    • insert_all(デフォルト動作: ON CONFLICT DO NOTHING)や upsert_all(ON CONFLICT DO UPDATE)はこれまで通りユニークインデックス/主キーの定義を前提とします。
    • つまり、「衝突をどう扱うか(skip/update)」を指定するメソッドは引き続きユニークインデックス必須です。
  • マイグレーションや既存コードへの影響

    • 既存で insert_all! 呼び出しがユニークインデックス不足で落ちていた場合、それが今後通るようになります。
    • 逆に、ユニークインデックスがないことで例外が起きていたのを、意図的な「安全装置」として利用していた場合は、その「保護」がなくなります(とはいえ、insert_all! 自体が ON CONFLICT を使わない設計なので、その挙動の方が一貫しています)。
    • 一括 INSERT 時に一意制約違反が起きた場合は、DB レイヤーで通常通りエラー(ActiveRecord::RecordNotUnique など)が発生します。この点は従来と変わりません。

  1. 参考情報 (あれば)
  • 対象 PR: https://github.com/rails/rails/pull/56666
  • 関連するメソッド:
    • ActiveRecord::Persistence#insert_all
    • ActiveRecord::Persistence#insert_all!
    • ActiveRecord::Persistence#upsert_all
  • 類似の設計: Rails のバルクインサート周りでは、「ON CONFLICT を使うメソッド(skip/update)」と、「素の INSERT を投げるメソッド(raise)」で、ユニークインデックス必須かどうかが分かれています。今回の修正はその方針をコードにも正しく反映したものと言えます。

#56652 Explicitly use Marshal serializer for MemCacheStore Dalli client

マージ日: 2026/1/23 | 作成者: @zzak

  1. 概要 (1–2文で)
    Rails の ActiveSupport::Cache::MemCacheStore が Dalli 4 系で出る「serializer 自動選択」の警告を避けるために、Rails 側で Dalli クライアントに対して明示的に Marshal シリアライザを指定するようにした PRです。これにより、もともとユーザーが変更できなかったシリアライザ設定を Rails がはっきり固定し、Dalli の警告を抑止します。

  1. 変更内容の詳細

背景

  • Rails の MemCacheStore は内部的に Dalli を使っています。
  • Dalli 4.0.0 では、シリアライザに Marshal がデフォルトで使われますが、「デフォルトの Marshal を自動で選んだ」という警告をログに出すようになりました。
  • 一方で Rails 側は、Dalli クライアントを初期化する際に serializer オプションを取り除いており、ユーザーは Rails 経由で Dalli の serializer を変更できない状態でした。
  • そのため、「どうせユーザーは変えられないのだから Marshal 前提で動いている」のに、Dalli からは「デフォルトの Marshal を自動選択した」という警告だけが出る、という微妙な状態になっていました。

この PR の対応方針

説明文の要点:

We can assume the default Marshal serializer will be used because the user can never change it, we remove it from the options before init.
Therefore, we can prevent Dalli from warning users about auto-selecting the default Marshal serializer.

要するに:

  • Rails は MemCacheStore で 常に Marshal を使う 前提になっている。
  • Dalli にクライアントを渡すときに「シリアライザは Marshal を使う」と 明示的に指定する ようにして、Dalli 側が「デフォルトを自動選択した」という警告を出さないようにする。

これに合わせて:

  • これまで Rails 側では serializer オプションを Dalli に渡す前に削除しており、ユーザーは serializer: を指定しても無視されていました。
  • 今回の修正で、Rails 自体が Marshal を使う前提をコード上でも明文化した形になります(Dalli に「Rails は Marshal を使う」と伝える)。

具体的なコード上の変更(概念レベル)

ActiveSupport::Cache::MemCacheStore が Dalli クライアントを作る箇所に、概ね以下のような意図の変更が入っています:

ruby
# 変更イメージ(擬似コード)
options = normalize_options(...) # Rails 内部のオプション処理

# 以前: options から :serializer を取り除いていた
# options.delete(:serializer)

# 今回: Dalli クライアントに Marshal serializer を明示的に渡す
options[:serializer] ||= Dalli::Marshal # 実際の定数名は Dalli の仕様に依存

Dalli::Client.new(servers, options)

※実際の実装は Dalli の API に合わせた形ですが、狙いは「Dalli から見て ‘ユーザーが明示的に Marshal を指定した’ 状態にする」ことです。

テストの変更:

  • activesupport/test/cache/stores/mem_cache_store_test.rb などで、Dalli 4 の新仕様に合わせた期待値・挙動にテストを修正。
  • cache_store_setting_test.rb 周辺で、MemCacheStore のオプション処理に関するテストが 1 行差し替え程度で調整されています。

Gemfile.lock:

  • Dalli 4.0.0 を前提にしたロックファイル更新が 1 行変更されています(テスト・CI 用の依存更新に近い意味合い)。

  1. 影響範囲・注意点

影響範囲

  • 対象: ActiveSupport::Cache::MemCacheStore を使用し、バックエンドが Dalli 4.x のアプリケーション。
  • 動作としては元々 Marshal 前提だったため、キャッシュフォーマット(Marshal でシリアライズされること)は従来通りで、挙動自体が変わるわけではありません。
  • 変化するのは主に「Dalli のログ・警告メッセージの出方」です。

期待できる効果

  • Dalli 4.0.0 で発生していた、MemCacheStore 利用時の以下のような警告が出なくなります:
    • 「デフォルトの Marshal serializer を自動選択した」旨の警告
  • Rails ユーザー側の認知としても、「MemCacheStore は Marshal 固定で動いている」ことがコードレベルでより明確になります。

注意点

  • serializer を Rails 側から自由に変えたかった、というニーズには現時点では対応していません。PR の説明にもあるように、もともと serializer オプションは Rails によって握りつぶされており、ユーザーはオーバーライドできませんでした。
  • Dalli 側の回避策としてドキュメントされている silence_marshal_warning オプション:
    • ユーザーは引き続き、Dalli に直接 silence_marshal_warning: true を渡すことで警告抑止が可能ですが、Rails 側が Marshal を明示するようになったことで、このオプションに頼らなくてもよくなるはずです。
  • 将来的に MemCacheStore が別の serializer(JSON など)をサポートするように設計変更される場合、今回の「Marshal を前提にした明示指定」は再検討が必要になります。

  1. 参考情報 (あれば)
  • 該当 Issue: #56588
    MemCacheStore + Dalli 4.0.0 での警告発生に関するバグレポート。
  • Dalli 4.0.0 Changelog:
    https://github.com/petergoldstein/dalli/commit/48290a73
    • デフォルト serializer 周りの仕様変更と警告メッセージが導入されています。
  • 対象コード:
    activesupport/lib/active_support/cache/mem_cache_store.rb
    activesupport/test/cache/cache_store_setting_test.rb
    activesupport/test/cache/stores/mem_cache_store_test.rb

#56667 Use the released version of net-smtp in bug report templates

マージ日: 2026/1/23 | 作成者: @yahonda

  1. 概要 (1-2文で)
    Rails のバグ報告テンプレート(action_mailbox.rbaction_mailer.rb)で、net-smtp の扱いを「リリース済み gem を使う」形に戻した PR です。以前の変更でテンプレート側に書かれていた一部設定を打ち消し、Gemfile 側の状態と整合を取っています。

  1. 変更内容の詳細

背景・モチベーション

  • 過去のコミット d84afbb1... で、net-smtp の扱いに関する変更(おそらく git リポジトリから直接取得する等)が行われていました。
  • しかし、その後のコミット acf76988... によって Gemfile が元の状態(= 通常のリリース版 net-smtp を使う構成)に戻されています。
  • Gemfile 側は元に戻ったのに、ガイドにあるバグ報告テンプレート内の記述だけが古い変更を引きずっていたため、それを「部分的に revert」して、現行の Gemfile 設定と揃えています。

実際の差分

変更ファイルは2つだけで、どちらも 1行削除(追加なし)という非常に小さい変更です。

  • guides/bug_report_templates/action_mailbox.rb (-1行)
  • guides/bug_report_templates/action_mailer.rb (-1行)

PR 本文からみると、この 1 行はいずれも「net-smtp に対して、リリースされていないバージョン/特別な取得方法を指定していた行」であり、これを削除することで:

  • バグ報告テンプレートを実行すると、net-smtp は通常通り rubygems.org に公開されているリリース版が解決される
  • Gemfile で既に復元されている挙動と一致する

という状態になります。

コード例として PR には直接 diff が載っていませんが、イメージとしては以下のような行が消えたと考えられます:

ruby
# 例: こういう「git から net-smtp を取る」行がテンプレから削除されたイメージ
# gem "net-smtp", github: "ruby/net-smtp", branch: "main"

現在は Gemfile が標準的な形に戻っているため、テンプレート側で net-smtp を特別扱いする必要がなくなり、その設定を削除しただけ、という変更です。

動作確認

PR では Ruby 4.0.1 で、両方のテンプレートが正常に動作することがログ付きで確認されています。

  • guides/bug_report_templates/action_mailbox.rb
    • Active Storage / Action Mailbox 用のテーブルが作成され、RepliesMailboxTest が 1テスト・1アサーションともに成功。
  • guides/bug_report_templates/action_mailer.rb
    • シンプルな TestMailer#hello_world が送信され、1テスト・7アサーションともに成功。
    • net-smtp を含むメール送信処理がリリース版 gem で問題なく動いていることが示されています。

  1. 影響範囲・注意点
  • 影響範囲

    • 影響を受けるのは「Rails のガイドにあるバグ報告テンプレートを、そのまま ruby guides/bug_report_templates/... で実行する人」です。
    • アプリケーション本体のコードや通常の Rails アプリの挙動には影響しません。
    • net-smtp を Rails 側でどう利用するか、というランタイム挙動も変えていません。あくまで「テンプレートでどのバージョンの net-smtp を取りに行くか」を揃えただけです。
  • 注意点

    • この PR によって、テンプレートは「公式にリリースされている net-smtp」を前提とするようになります。そのため、もし net-smtp の unreleased な変更に依存したバグ報告をしたい場合は、テンプレートを自分で編集して指定する必要があります。
    • 逆にいうと、標準的な環境でのバグ再現用テンプレートとしてはより安定・再現性の高い状態になります。

  1. 参考情報 (あれば)

これら2つのコミットとの整合を取るための微調整が、この PR の主な目的です。


#56657 Prefer connected? for connection validity checks

マージ日: 2026/1/23 | 作成者: @matthewd

  1. 概要 (1-2文で)
    ActiveRecord の DB 接続の「有効性チェック」において、active? ではなく connected? を優先的に使うように変更し、「一度ダメになった接続はその後も使えない」と記録して扱うようにした PR です。これにより、「すでに壊れている」ことが判明したコネクションを再利用しない挙動がより明確になります。

  1. 変更内容の詳細

a. 抽象アダプタ (abstract_adapter.rb)

変更点は小さいですが、接続が有効かどうかを判断する箇所で active? ではなく connected? を使うように揃えた、という趣旨の修正です。

もともと多くのコードパスでは

ruby
if active?
  # 接続は使える前提でクエリ実行
end

のように「今まさに生きているか」を確認していましたが、PR の説明にある通り active? を呼ぶと「接続が壊れている場合にそれを検知してマークする」副作用を持つようになっています。
この PR では、「一度 bad と判定されたら connected? が false を返すようになる」という前提で、今後は基本的に

ruby
if connected?
  # 一度も壊れたことがない / 少なくとも今は bad とマークされていない
end

のように connected? を接続の有効性チェックとして扱う方向に寄せています。

ここでポイントなのは:

  • active? は「実際に DB に問い合わせてみて、壊れていたら bad とマークする」動き
  • connected? は「既に bad と判定された接続なら false、そうでなければ true」を返すキャッシュ的な役割

を明確に分けるようになったことです。

b. PostgreSQL アダプタ (postgresql_adapter.rb)

PostgreSQL 用アダプタでも、内部実装で接続状態を確認する箇所において active? ではなく connected? を利用するように修正されています。

例としてイメージすると:

変更前 (イメージ)

ruby
def some_method
  return unless active? # ここで DB への実問い合わせ + bad マーク
  # クエリ実行 or その他処理
end

変更後 (イメージ)

ruby
def some_method
  return unless connected? # ここでは「もう bad とわかっているか」だけを見る
  # クエリ実行 or その他処理
end

これにより、「すでに壊れていると判明した接続を避ける」ことに重点を置きつつ、「チェックするたびに毎回 DB を叩く」ような挙動を減らす意図があります。

c. テスト (adapter_test.rb)

PR 説明にある通り、テストが分割されています。

  • 以前のテストでは active? を呼んだ後に「障害のある接続」でクエリを実行するテストを書いていた
  • しかし今回の挙動変更で、active? が「接続を bad とマークし、その後に自動的に再接続してしまう」ため、「壊れた接続でクエリを投げたいテスト」になっていなかった

そのため:

  • active? を呼ぶことで接続状態が変化してしまう副作用を避けるためにテストケースを分割
  • 1つは「接続が壊れたことを検出して bad とマークするテスト」
  • もう1つは「bad とマークされた接続に対して、その後 connected? が false を返し再利用されないことを確認するテスト」

というように、意図したシナリオごとに独立したテストになっています。


  1. 影響範囲・注意点
  • 「新たに発生した切断」は検知しない可能性がある
    説明にもある通り、この PR は「新しく起きた物理的な切断」を積極的にキャッチするものではありません。

    • 例: コネクションがしばらく idle で、DB 側で切断された、など
    • こうした「fresh disconnections」は、依然としてクエリ実行時などに例外として表面化し、そのタイミングで active? 相当のチェックが走って bad とマークされる想定です。
  • 一度 bad になった接続は今後 connected? で false と判定される
    そのため、アプリケーション側で connected? に依存して「接続がある/ない」を判定している場合、より保守的な挙動になります。

    • 以前なら「次の active? 呼び出しで再接続して使えるかも」だったものが
    • 今回以降は「bad とわかった接続は connected? が false を返し、新規接続が必要」という流れが明確になります。
  • active? をアプリケーションコードから直接多用している場合は注意

    • active? は「チェックするときに接続状態を確定させる」メソッドになりつつあるため、
      • 頻繁に呼ぶと余計な DB ラウンドトリップが増える
      • かつ「接続を bad とマークした上で、アダプタ側が自動的に再接続する」動きと組み合わさると、テストや実運用で予期しない再接続が起きる可能性があります。
    • ライブラリ・アプリ側で「単に今このプールに有効な接続があるか」を知りたい場合は、将来的には connected? のような「状態キャッシュ寄り」のメソッドを使うのが安全です。
  • テストの前提が変わる

    • active? を呼んでも状態は変わらない」という前提で書かれたテストは壊れる可能性があります。
    • この PR のように、「active? を挟まない」テスト構造に見直すことで、意図通りの状態を再現できるか確認した方がよいです。

  1. 参考情報 (あれば)
  • PR タイトルの "Prefer connected? for connection validity checks" から読み取れる意図:
    • 「接続の健全性チェック」は active? よりも connected? を第一候補にし、「active? は必要時にのみ DB に問い合わせて状態を更新する」役割に寄せる整理。
  • 似た問題領域:
    • コネクションプールの checkout / checkin 処理
    • DB 障害時のフェイルオーバー・自動再接続ロジック
    • long-running job (Sidekiq, Active Job) 実行中のコネクション切断ハンドリング

この PR 自体のコード変更量は小さいものの、「接続状態をどう定義し、どのメソッドでどこまで保証するか」という設計方針に関わるため、コネクション管理まわりのメソッド (connected?, active?, verify! など) を独自にオーバーライドしているアダプタやライブラリでは挙動を確認しておくと安全です。


#56663 Upgrade from bundler 2.7.2 to 4.0.4

マージ日: 2026/1/22 | 作成者: @larouxn

  1. 概要 (1-2文で)
    Rails本体の開発環境で使用する Bundler のバージョンが 2.7.2 から 4.0.4 に更新された PR です。コード変更は Gemfile.lock の Bundler バージョン指定を 1 行変更したのみの、極小のメンテナンス更新です。

  1. 変更内容の詳細
  • 変更ファイル: Gemfile.lock
  • 変更内容: Bundler のバージョン行を更新

イメージとしては、Gemfile.lock の末尾付近が:

diff
-BUNDLED WITH
-   2.7.2
+BUNDLED WITH
+   4.0.4

という形で更新された、という内容です。
Gem の依存関係やバージョンには手を入れておらず、Bundler 自体のバージョン宣言だけが新しい安定版 (4.0.4) に揃えられています。


  1. 影響範囲・注意点
  • 開発環境での Bundler バージョン統一

    • .ruby-version がリポジトリに含まれていないため、開発者ごとに利用 Ruby が異なりうる状況で、Bundler のバージョンだけは 4.0 系で統一されます。
    • 特に Ruby 4 系を使うとデフォルトで Bundler 4 になるため、Ruby 3.3 / 3.4 などを使っている開発者も bundle _4.0.4_ 相当で動かすことになり、環境差異による問題を減らせます。
  • 実行時挙動

    • Rails 自体のアプリケーションコードや依存 Gem のバージョンは変えていないため、この PR だけで Rails の挙動が変わることは基本的にありません。
    • ただし、Bundler 4 は 2.x 系からいくつか動作や警告メッセージが変わっている可能性があるため、開発・CI 環境で bundle installbundle exec の挙動がわずかに変わる可能性があります。
  • 実務での注意点 (Rails コントリビュータ視点)

    • ローカルで Rails を開発する場合、手元の Bundler が 4.0.4 以外だと Gemfile.lock を更新してしまう可能性があります。
      • 例: 手元が 2.x のままだと bundle install 実行時に BUNDLED WITH が 2.x に戻ってしまう。
    • この PR マージ後は、Rails リポジトリで開発する際は Bundler 4.0.4(もしくは少なくとも 4.0 系)にアップデートしておくのが無難です。

  1. 参考情報 (あれば)

PR で挙げられている関連リンク:

Bundler 4 系全体の変更点や互換性が気になる場合は、上記のリリースノートとブログを読むと具体的な差分や推奨アップグレード手順が把握できます。


#56665 Add &block params to ActionController methods using yield

マージ日: 2026/1/22 | 作成者: @dduugg

  1. 概要 (1-2文で)
  • ActionController 内で yieldblock_given? を使っているにもかかわらずメソッド引数に &block が明示されていなかった箇所に、すべて &block パラメータを追加した PR です。
  • 実行時の挙動は一切変えず、静的解析ツール(特に Sorbet)やドキュメント生成、シグネチャの一貫性を改善するメンテナンス目的の変更です。

  1. 変更内容の詳細

2-1. 何をしているか

以下のように、「もともとブロックを yield で呼び出していたが、メソッド定義には &block がなかった」メソッドに、&block が追加されています。

strong_parameters.rb

  • fetch(key, *args)
    fetch(key, *args, &block)

  • transform_values
    transform_values(&block)

  • transform_values!
    transform_values!(&block)

  • each_nested_attribute
    each_nested_attribute(&block)

これらはいずれも内部で block_given?yield を使っており、元々ブロックを受け取れる実装になっていたが、シグネチャ上は&blockがなかった、という状態でした。

サンプルイメージ(実際の実装イメージ):

ruby
def transform_values(&block)
  # 以前は def transform_values だけだったが、
  # 中で yield を呼んでいたようなケース
  if block_given?
    # 各値に対してブロックを適用
    # ...
  else
    # ...
  end
end

Sorbet などの静的解析では

  • メソッドシグネチャに &block がない
  • でも中で yield している

という状態は「ブロックが引数に宣言されていないのに使われている」として警告やエラーの原因になります。そのため、シグネチャ側にも &block を明示しました。

live.rb

  • send_stream(filename:, disposition:, type:)
    send_stream(filename:, disposition:, type:, &block)

ActionController::Live#send_stream はストリーミングレスポンスを扱うメソッドで、ブロックを受け取ってその中で response.stream を書き込むパターンがよくあります。このブロック受け取りがシグネチャ上も明示されます。

ruby
send_stream(filename: "export.csv", disposition: "attachment", type: "text/csv") do |stream|
  # CSVを書き出す処理
end
  • new_controller_thread
    new_controller_thread(&block)

ライブストリーミングなどでコントローラ処理を別スレッドで実行するユーティリティで、内部でブロックを新しいスレッドに渡していたものと思われます。これも &block をシグネチャに追加。

instrumentation.rb

  • cleanup_view_runtime
    cleanup_view_runtime(&block)

レンダリングまわりの計測・ロギングに使われるメソッドで、yield によって計測対象のブロックを呼び出す構造になっています。これも正式に &block を受けることがシグネチャ上明示されます。

conditional_get.rb

  • http_cache_forever(public:)
    http_cache_forever(public:, &block)

「永続的にキャッシュ可能なレスポンス」を返すためのユーティリティで、ブロックの戻り値をキャッシュ対象コンテンツとして扱うような構造です。ブロック必須/任意かどうかも、シグネチャから読み取りやすくなります。

使用イメージ:

ruby
http_cache_forever(public: true) do
  # キャッシュされるレスポンスボディ等を生成
end

mime_responds.rb

  • respond_to(*mimes)
    respond_to(*mimes, &block)

respond_to は非常に頻繁に使われるコントローラ DSL で、以前からブロック前提の使い方が一般的でした:

ruby
respond_to do |format|
  format.html
  format.json { render json: @resource }
end

これ自体ずっと動いていましたが、静的解析や自動ドキュメント生成の観点から、&block を定義にも追加して整合性をとっています。


  1. 影響範囲・注意点
  • 実行時の互換性:
    Ruby では、メソッド内で yield を使っている場合、呼び出し側がブロックを渡していれば問題なく動きます。ここに &block を追加するだけでは、呼び出しコードもメソッド内の処理も変わらないため、ランタイムの挙動は変わりません(完全後方互換)。

  • 静的解析ツールへの影響:
    Sorbet などで

    • 「メソッド定義に &block がないのにブロックを渡している」と怒られるパターン
    • 「メソッド定義に &block がないのに内部で yield している」と怒られるパターン

    が解消され、型シグネチャや RBI 生成が素直になります。

  • ドキュメント・補完への影響:
    YARD や IDE のシグネチャ表示に &block が出るため、
    「このメソッドはブロックを受け取るのか?」というのが明示され、API 利用者には分かりやすくなります。
    特に respond_to, send_stream, http_cache_forever のような DSL 的メソッドでは恩恵が大きいです。

  • テスト・CHANGELOG なしについて:
    仕様も挙動も変えていない(あくまでシグネチャの明示)ため、テストや CHANGELOG の更新は不要と判断されています。既存テストがすべて通ることが前提です。


  1. 参考情報 (あれば)
  • Sorbet 側の関連 PR:
    https://github.com/sorbet/sorbet/pull/9791
    → ブロックパラメータ検査と、この PR のような変更が必要になる背景が説明されています。

  • Rails コード上の近い例:
    同じファイル内にすでに each_pair(&block)transform_keys(&block) など、ブロックを明示した同系統メソッドが存在しており、それらとシグネチャを揃えたかたちです。


#56656 Update Dockerfile.test fixture to use Ruby 3.3

マージ日: 2026/1/22 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Rails のテスト用フィクスチャ Dockerfile.test が、使用する Ruby バージョンを 3.2.2 から 3.3.0 に更新する PR です。
    これは、別 PR (#56511) で Ruby 3.2 サポートが正式にドロップされ、Rails の要求する最小 Ruby バージョンが 3.3 になったことに合わせた追従変更です。

  1. 変更内容の詳細

対象ファイル: railties/test/fixtures/Dockerfile.test
変更内容は 1 行のみで、ベースイメージとして使う Ruby バージョンの更新です。

イメージとしては以下のような変更になっています(実際の Dockerfile は簡略化):

diff
-FROM ruby:3.2.2
+FROM ruby:3.3.0

つまり、Rails 内部テストで利用される Dockerfile の「Ruby バージョン指定」を、現行のサポートポリシーに沿って Ruby 3.3 系にアップデートしただけの変更です。

ここでの Dockerfile.test は Rails のテストスイート用フィクスチャ(テストで利用されるサンプルファイル)のひとつであり、実際の Rails アプリケーション用 Dockerfile ではなく、「Rails が Docker 関連機能を扱う際のテスト素材」という位置づけです。


  1. 影響範囲・注意点
  • Rails 本体への影響

    • Rails コアコードの挙動や API には影響しません。
    • 影響するのは、railties のテストで Dockerfile.test を参照するテストケースのみです。
  • 開発者・利用者への影響

    • Rails をライブラリとして利用しているアプリケーションには直接の影響はありません。
    • ただし、Rails 本体のサポート Ruby バージョンが 3.3 以上になっていることを改めて示す変更なので、Rails edge / 7.2 以降などを追従している開発者は、Ruby 3.2 ではなく 3.3 以上を使うことを前提に環境を整える必要があります。
    • 自身のプロジェクトで Rails のこの Dockerfile.test を参考に Dockerfile を書いていた場合、Ruby 3.3 への更新のタイミングを検討すべきです。
  • CI / テストへの影響

    • Rails リポジトリ内で、Dockerfile.test をそのまま使ってコンテナをビルド・テストしている場合、以降は Ruby 3.3.0 イメージが取得されます。
    • 手元や CI に Ruby 3.3 系の Docker イメージを前提としたキャッシュ・ミラー設定が必要な場合があります。
  • 注意点

    • Ruby 3.3 固有の挙動(パフォーマンスや警告、JIT 周りなど)が、Docker 上のテスト挙動に影響する可能性はありますが、この PR 自体は単なるバージョン番号の更新に留まっています。
    • Ruby 3.2 以前向けのサポート・互換性を検証したい場合は、過去バージョンの Dockerfile.test を参照する必要があります。

  1. 参考情報 (あれば)

#56660 Fix: Correct typo in routing guide [ci skip]

マージ日: 2026/1/22 | 作成者: @mutumagitonga

  1. 概要 (1-2文で)
    Railsのルーティングガイド内に記載されていたヘルパーメソッド名のタイプミス(new_photos_path)を、正しい名前(new_photo_path など)に修正したドキュメント専用のPRです。コード本体への変更はなく、ガイドの記述だけが1行修正されています。

  1. 変更内容の詳細
  • 対象ファイル: guides/source/routing.md
  • 変更内容: ルーティングヘルパーの名前から不要な "s" を削除

RailsのRESTfulルーティングでは、典型的に以下のような命名規則になります:

ruby
resources :photos

この場合に生成される主なパスヘルパーは:

  • 一覧: photos_path
  • 新規作成フォーム: new_photo_path
  • 詳細: photo_path(photo)
  • 編集フォーム: edit_photo_path(photo)

ドキュメントには本来 new_photo_path と書くべきところが、new_photos_path のように複数形で記載されていたため、s を1文字削除して正しい例示に揃えた、という内容です。
(正確な最終名はPR本文の文脈から「余計な s を消した」ことだけが明示されていますが、Railsのガイド文脈的には new_photo_path への修正である可能性が高いです。)


  1. 影響範囲・注意点
  • 影響範囲:

    • Rails本体の動作・API・挙動には一切影響しません。
    • ガイドを見ながらルーティングを書く開発者が、誤ったヘルパー名をコピペしてエラーになる、という混乱が減ります。
  • 注意点:

    • すでに new_photos_path のような誤ったヘルパー名を使っていた場合、それは元から存在しないメソッドであり、このPRによって新たに非互換が発生することはありません。
    • 今後ガイドを参照する際は、resources で定義される単数形/複数形のヘルパー対応を改めて意識するとよいです。
      • 複数形: コレクション (photos_path, photos_url)
      • 単数形: 個別リソース/フォーム (new_photo_path, edit_photo_path, photo_path(photo))

  1. 参考情報 (あれば)
  • Rails Routing from the Outside In (公式ガイド):
    https://guides.rubyonrails.org/routing.html
    このPRは上記ガイド(日本語版ではなく原文)の routing.md に対する修正です。
  • 生成されるルーティングとヘルパーの一覧は、実プロジェクトで bin/rails routes を実行すると確認できます。

#56661 Fix typos and minor errors in guides [ci skip]

マージ日: 2026/1/22 | 作成者: @eglitobias

  1. 概要 (1-2文で)
    このPRは、Railsガイド(ドキュメント)内の誤字、表現ゆれ、軽微な不正確さを修正するものです。コード本体の挙動やAPI仕様には変更がなく、あくまでドキュメント品質向上のみが目的です。

  1. 変更内容の詳細

対象は以下の6つのガイドファイルで、それぞれ文章・語句レベルの修正が行われています。

  • guides/source/action_controller_overview.md
  • guides/source/active_record_callbacks.md
  • guides/source/active_record_encryption.md
  • guides/source/active_record_postgresql.md
  • guides/source/active_record_querying.md
  • guides/source/active_record_validations.md

行数統計から見ると、各ファイルで「+?/-?」が対になっており、内容面では以下のようなタイプの修正が想定されます(PR説明と行数からの推測を含みます):

  • タイポ修正
    • 例: recievereceive などの綴りミス
    • モジュール名・クラス名の表記ゆれ (例: ActiveRecord → Active Record)
  • 用語・表現の統一
    • 「callback」や「validation」など、Railsで慣例的に使われる用語の統一
    • ガイド全体のスタイルガイド(Rails Guides Style Guide)に沿った言い回しへの修正
  • 軽微な不正確さの修正
    • 説明とコード例の乖離を埋める修正
    • PostgreSQLの機能名・設定名の細かい表記揺れや誤記
    • 暗号化(Active Record Encryption)の説明文のニュアンス調整(例: 「暗号化されるのは列だけ」→「データベースに保存される属性値が暗号化される」など、より正確な言い回し)

実際のコード例のAPI呼び出しそのものが変わっているというよりは、コメント・説明文・単語レベルの修正が中心であると考えられます。
(差分が11行追加・11行削除と、ごく小さいことからも大規模な例の書き換えは行われていないと見込まれます。)


  1. 影響範囲・注意点
  • 影響範囲

    • Rails本体の挙動・パブリックAPI・バグ修正には一切関係なく、「ガイドを読む開発者」にのみ影響します。
    • 対象バージョン以降の Rails Guides を閲覧した際に、より正確で読みやすい文章になっている程度の差分です。
  • 注意点

    • 既存アプリケーションやテストコードの修正は不要です。
    • 社内ドキュメントやブログ記事などで Rails Guides の文章を引用している場合、細かい文言差分が発生する可能性はありますが、意味が変わるレベルではないと考えてよいです。
    • ガイドを翻訳している場合(特に非英語版)、原文の微修正に追従が必要になる可能性があります。

  1. 参考情報 (あれば)
  • PRタイトルに [ci skip] が含まれていることからも分かる通り、実行可能コードには触れておらず、CIを回す必要のない文書修正のみのPRです。
  • Rails の公式ガイドは頻繁にこうした小さな修正が入り、バグ修正・機能追加と同じブランチに乗ることがあります。
    ドキュメントを信用してよいかという観点では、今回のようなPRにより継続的に品質が改善されていると見てよいです。

#56655 Detect bun JS package manager when using text-based lockfile

マージ日: 2026/1/22 | 作成者: @bai

  1. 概要 (1-2文で)
    Rails の JavaScript パッケージマネージャ自動検出ロジックにおいて、bun のロックファイルとして旧形式の bun.lockb だけでなく、新しいテキスト形式の bun.lock も検出対象に追加した PR です。これにより、現行の bun プロジェクトでも Rails が正しく「bun を使用している」と認識できるようになります。

  1. 変更内容の詳細

JS パッケージマネージャ検出ロジックの更新

対象ファイル: railties/lib/rails/generators/js_package_manager.rb

以前の PR (#56636) で、Rails は JS パッケージマネージャを「ロックファイルの存在」で判定するようになりましたが、bun については古いバイナリ形式の bun.lockb のみを見ていました。

この PR では、bun 検出条件が次のように変わります(疑似コードイメージ):

ruby
# 変更前(イメージ)
if File.exist?("bun.lockb")
  :bun
end

# 変更後(イメージ)
if File.exist?("bun.lockb") || File.exist?("bun.lock")
  :bun
end

bun は現在、デフォルトでテキスト形式の bun.lock を使うため、これを検出対象に含めることで、最新の bun プロジェクトを正しく bun プロジェクトとして扱えるようにしています。

テストの追加

対象ファイル:

  • railties/test/generators/js_package_manager_test.rb
  • railties/test/generators/action_text_install_generator_test.rb

おおまかな内容:

  • js_package_manager_test.rb
    • bun.lock が存在する場合に、JsPackageManager.detect(等の検出処理)が :bun を返すことを確認するテストが追加されています。
  • action_text_install_generator_test.rb
    • ActionText のインストールジェネレータが、bun.lock の存在するプロジェクトで bun を選択して動作することを確認するテストが追加されています。
    • これにより、Action Text のセットアップ時に bun が適切に検出されることが保証されます。

コード上の実質的な変更行数は少なく(合計 15 行追加・1 行削除)、機能の追加というより検出条件の微修正と、それを担保するテスト追加が主な内容です。


  1. 影響範囲・注意点
  • 影響範囲

    • Rails ジェネレータで JS パッケージマネージャを自動検出する処理(rails new 後の設定や、action_text:install など)が、bun.lock を持つプロジェクトで bun を自動選択するようになります。
    • すでに bun.lock を使っている Rails + bun プロジェクトでは、これまで yarnnpm など別のマネージャと誤認されていたケースが、今後は bun として処理される可能性があります。
  • 互換性・注意点

    • 旧ロックファイル bun.lockb も引き続き検出対象に含まれているため、古い bun プロジェクトとの後方互換性は保たれています。
    • lockfile 名の追加のみであり、bun 自体のインストールやコマンドの実行方法(bun install, bun add など)の挙動には変更はありません。
    • bun.lock と他のパッケージマネージャのロックファイル(package-lock.json, yarn.lock, pnpm-lock.yaml など)が同時に存在するような特殊ケースでは、Rails 側のマネージャ優先順位ロジックに従った結果になります。今回の PR は「bun を検出対象に増やしただけ」で、優先順位自体の変更はしていません。

  1. 参考情報 (あれば)
  • 対応する以前の PR:
  • bun の lockfile 仕様(参考):
    • 旧: bun.lockb(バイナリ形式)
    • 新: bun.lock(テキスト形式、現在のデフォルト)
  • bun を Rails で使う場合に関連しうる箇所:
    • rails new 時の JS パッケージマネージャ選択
    • action_text:install 等のジェネレータによる依存パッケージ追加処理

#56636 Detect JS package manager from lockfiles in generators

マージ日: 2026/1/21 | 作成者: @dfl

  1. 概要 (1-2文で) Rails のジェネレータ(ActionText, ActionCable など)が、プロジェクト内の lockfile から JavaScript のパッケージマネージャ(bun / pnpm / npm / yarn)を自動判別してコマンドを実行するようになりました。これにより「常に yarn 前提」だった動作が解消され、npm や pnpm 等を使うプロジェクトでも手作業の修正が不要になります。

  1. 変更内容の詳細

2-1. 全体像

今回の PR では、JavaScript パッケージマネージャ関連の処理を Rails::Generators::JsPackageManager というモジュールに集約し、以下を担当させています。

  • どのパッケージマネージャを使うかの自動検出
  • add / install / audit などのコマンド文字列の管理
  • lockfile のファイル名の管理

このモジュールを、ActionText / ActionCable のジェネレータや、古くからある yarn 関連の rake タスクから利用するように変更しています。


2-2. パッケージマネージャの自動検出ロジック

検出は「lockfile の存在」で行われ、優先順位は以下の通りです。

  1. bun.lockb → bun
  2. pnpm-lock.yaml → pnpm
  3. package-lock.json → npm
  4. yarn.lock またはロックファイル不在 → yarn(デフォルト)

疑似コードで表すと、以下のような形と考えてよいです:

ruby
module Rails::Generators::JsPackageManager
  LOCKFILES = {
    "bun"  => "bun.lockb",
    "pnpm" => "pnpm-lock.yaml",
    "npm"  => "package-lock.json",
    "yarn" => "yarn.lock"
  }

  def self.current
    return "bun"  if File.exist?("bun.lockb")
    return "pnpm" if File.exist?("pnpm-lock.yaml")
    return "npm"  if File.exist?("package-lock.json")
    return "yarn" # yarn.lock があればそれ、なければデフォルト
  end
end

※ 実際のコードはもう少し抽象化されており、テストも追加されています。


2-3. コマンド文字列の抽象化

ジェネレータ側は「どのコマンドを使うか」を意識せず、「パッケージを追加したい」「インストールしたい」といった抽象的な操作を呼び出すだけになります。

たとえば、パッケージ追加のためのコマンドはパッケージマネージャごとに次のように変わります(イメージ):

  • bun: bun add <package>
  • pnpm: pnpm add <package>
  • npm: npm install <package> --save(あるいは類似の形)
  • yarn: yarn add <package>

Rails::Generators::JsPackageManager 側でこれらのテンプレート文字列を管理し、ジェネレータは「パッケージ名だけ渡す」形になります。

ActionText のインストールジェネレータ中の変更イメージ:

ruby
# 変更前(概念的な例)
run "yarn add @rails/actiontext"

# 変更後(概念的な例)
run JsPackageManager.add("@rails/actiontext")

これにより、ジェネレータを変更せずに、プロジェクトごとの JS パッケージマネージャに合わせたコマンドが呼ばれるようになります。


2-4. 適用されるジェネレータ / タスク

PR の diff から読み取れる対象は以下です:

  • actioncable/lib/rails/generators/channel/channel_generator.rb
    • チャネルジェネレータが用いる JS 関連のセットアップ処理が yarn 固定から抽象化された。
  • actiontext/lib/generators/action_text/install/install_generator.rb
    • action_text:install 実行時に呼ばれる JS 依存関係インストールの処理が JsPackageManager 経由に変更。
  • railties/lib/rails/tasks/yarn.rake
    • 以前は yarn コマンド前提で書かれていた rake タスクが、パッケージマネージャ抽象化を利用するように変更。

具体的に ActionText のテスト (action_text_install_generator_test.rb) には、環境ごと(npm / yarn / pnpm など)の lockfile を用意し、その状況でどのコマンドが呼ばれるかを検証するテストが追加されています。

また、新規に以下のテストが追加されています。

  • railties/test/generators/js_package_manager_test.rb
    • bun.lockb があるときは bun を選ぶ
    • pnpm-lock.yaml があるときは pnpm を選ぶ
    • package-lock.json があるときは npm を選ぶ
    • いずれもないまたは yarn.lock があるときは yarn といった挙動が自動テストで保証されています。

  1. 影響範囲・注意点

3-1. 影響範囲

  • Rails ジェネレータを用いて JS パッケージを追加・インストールする箇所全般
    • ActionText (action_text:install)
    • ActionCable のチャネルジェネレータ
    • 既存の yarn 関連 rake タスク(実質的に JS 依存インストールに関わるもの)

これらは「yarn 前提」ではなく、「lockfile に合わせたコマンドを実行する」挙動になります。

3-2. 既存プロジェクトへの影響

基本的には後方互換ありです。

  • Yarn を使っていたプロジェクト

    • これまで通り yarn.lock が存在していれば yarn が選ばれ、そのまま動きます。
    • yarn.lock がなくても、他の lockfile がなければデフォルトで yarn が選択されるため、挙動は大きくは変わりません。
  • npm / pnpm / bun を使っているプロジェクト

    • lockfile が存在する場合、今後はジェネレータ実行時にそのパッケージマネージャのコマンドが自動で使われるようになります。
    • これまではジェネレータ実行後に package.json の依存を手で直したり、yarn で入れられた lockfile を消したりといった手作業が必要でしたが、その必要が減ります。

3-3. 注意点

  • 複数の lockfile が混在しているような「汚れた」状態は想定外

    • たとえば yarn.lockpackage-lock.json が共存している場合、実際の実装がどの順で探索しているかに依存します(PR 説明では bun → pnpm → npm → yarn の順と明記)。
    • プロジェクトとしてどのパッケージマネージャを使うかを明確にし、不要な lockfile は削除しておくことが望ましいです。
  • lockfile のみで判定しているため、

    • 「npm を使うつもりだが、まだ npm install を実行していない(lockfile がない)」状態では yarn が選ばれます。
    • 最初から npm / pnpm / bun を使いたい場合は、先に一度 npm install / pnpm install / bun install を実行して lockfile を作っておくとよいです。

  1. 参考情報 (あれば)
  • 元 issue: Fixes #47416
    → 「ジェネレータが yarn 前提であるため npm / pnpm 利用時に毎回手修正が必要」という問題を解消する PR。
  • 新規ファイル:
    • railties/lib/rails/generators/js_package_manager.rb (~80 行)
      • パッケージマネージャ検出とコマンド生成の中核モジュール。
  • 関連テスト:
    • railties/test/generators/js_package_manager_test.rb
    • railties/test/generators/action_text_install_generator_test.rb

この PR により、「Rails のジェネレータを使うと勝手に yarn 用の記述が入る」という不満が解消され、JS パッケージマネージャの選択がプロジェクト側の lockfile によって自然に反映されるようになります。


#56552 [ci skip] Add sample code on API docs about Active Job Continuation Configuration

マージ日: 2026/1/21 | 作成者: @igaiga

  1. 概要 (1-2文で)
    Active Job の「Continuation」機能に関する API ドキュメントに、具体的な設定例(サンプルコード)が追加された PRです。挙動や API 仕様には変更を加えず、使い方を分かりやすくするためのドキュメント強化が目的です。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル: activejob/lib/active_job/continuation.rb
  • 実コードのロジック変更はなく、「Continuation の設定」に関する YARD コメント(API ドキュメント)にサンプルコードが 8 行分追加された変更です。
  • 追加されたサンプルの主なポイント:
    • 「Active Job Continuation をどう設定するか」が、アプリケーションレベルの設定例として書かれている。

    • 想定される例としては以下のような形です(※実際の PR はこれとほぼ同趣旨の例がコメントに書かれていると考えられます):

      ruby
      # config/application.rb など
      
      class Application < Rails::Application
        # Active Job Continuation のアダプタ設定例
        config.active_job.continuation_app = "MyFrontendApp"
      
        # Continuation のキュー名やオプションを指定する例
        config.active_job.continuation_queue_name = :default
      end
    • あるいは、Continuation を利用したジョブクラスの利用例が含まれている可能性があります:

      ruby
      class SomeJob < ApplicationJob
        def perform(user_id)
          # メイン処理
        end
      
        continuation_on :success, queue: :low_priority
      end

どのようなキー(設定項目)をどこでどう書くかが、コード例で示されているため、ActiveJob::Continuation の API ドキュメントから直接コピペして使える形を目指した変更になっています。


  1. 影響範囲・注意点
  • 影響範囲:
    • ランタイムの挙動や既存アプリケーションの動作には一切影響しません。
    • 変更は continuation.rb 内のコメント(ドキュメント)部分のみです。
  • 注意点:
    • 新しい設定オプションが追加されたわけではなく、「既存の Continuation 機能の設定方法をサンプル付きで明示した」だけの変更です。
    • もし過去に Continuation 機能を読んでも使い方が分かりづらかった場合、最新の API ドキュメント(Edge Guides / API Docs)を見直すと、今回追加されたサンプルで理解しやすくなっている可能性があります。
    • PR 説明にもある通り、「もしサンプルが設計意図と合わなければ今後修正される」前提で書かれているため、将来バージョンでサンプルが微調整される可能性はありますが、互換性の破壊には直結しません。

  1. 参考情報 (あれば)
  • Active Job Continuation 機能そのもののリファレンス(英語):
    • Rails Edge API (該当クラス: ActiveJob::Continuation もしくは近い名前空間)
  • PR メタ情報:
    • タイトル: [ci skip] Add sample code on API docs about Active Job Continuation Configuration
    • CI をスキップしていることからも分かる通り、テストが不要な「ドキュメントのみ」の変更として扱われています。
  • 実際のサンプルコードやオプション名の正確な確認には、該当バージョンの API ドキュメントもしくは activejob/lib/active_job/continuation.rb のコメントを参照してください。

#56250 Deduplicate logic for internal params handling in Action Controller log subscriber

マージ日: 2026/1/21 | 作成者: @lovro-bikic

  1. 概要 (1-2文で)
    ActionController のログ周りで「内部パラメータ(internal params)」を除外する処理が二重に書かれていたため、その重複を解消し、StructuredEventSubscriber#start_processing 側に一本化した PR です。結果として、ログ出力時のパラメータフィルタリングの責務が整理され、コードが簡潔になりました。

  1. 変更内容の詳細

背景

Rails 7.2 以降(PR #55334)で導入された structured events により、ActionController::StructuredEventSubscriberrequest_started イベントを発火し、それを ActionController::LogSubscriber が受けてログ出力を行う流れになっています。

現在の流れは概ね以下のようなイメージです:

ruby
# StructuredEventSubscriber
def start_processing(event)
  # params から internal keys を除外する処理がここにある
  filtered_params = filter_internal_params(params)

  ActiveSupport::Notifications.instrument("request_started.action_controller",
    controller: controller_name,
    action: action_name,
    params: filtered_params,
    # ...
  )
end

# LogSubscriber
def request_started(event)
  payload = event.payload
  params  = payload[:params] # ここですでに internal keys が除外された Hash を受け取る
  # ...
end

この PR 以前は、LogSubscriber 側でも再度 internal params を取り除くようなロジックが残っており、同じフィルタリング処理が二重に存在していました。

具体的な変更

対象ファイルは 1 つだけです。

  • actionpack/lib/action_controller/log_subscriber.rb
    • internal params を除外するためのロジックを削除(-6行)
    • StructuredEventSubscriber から渡される params をそのまま利用するように簡略化(+1行)

コードイメージとしては:

diff
def request_started(event)
  payload = event.payload
- params  = payload[:params] || {}
-
- # ここで internal params を削除していたような処理が削除された
- params = remove_internal_params(params)
-
- info "Processing by #{payload[:controller]}##{payload[:action]} as #{payload[:format]} with #{params.inspect}"
+ params  = payload[:params] || {}
+ info "Processing by #{payload[:controller]}##{payload[:action]} as #{payload[:format]} with #{params.inspect}"
end

実際のメソッド名やログ文言は多少違う可能性がありますが、ポイントは「LogSubscriber 側では、もう internal params を意識しない」ようになったことです。
internal params の除外は完全に StructuredEventSubscriber#start_processing の責務になりました。


  1. 影響範囲・注意点
  • ログの内容自体は(設計上は)変わらない想定
    もともと StructuredEventSubscriber#start_processing 側で internal params を削除してから request_started を emit しているため、LogSubscriber から見える params はすでに「内部キー除外済み」の Hash です。この PR はあくまで「二度目のフィルタリングを消しただけ」であるため、正常系ではログの出力内容は変わらない設計です。

  • internal params フィルタの単一責務化
    internal params の除外箇所が StructuredEventSubscriber に一本化されたので、

    • internal params の定義変更
    • 除外条件の変更 を行う場合は StructuredEventSubscriber#start_processing 周辺だけを見ればよくなります。
      ログ周りのバグ調査や仕様変更がしやすくなります。
  • カスタム Subscriber を書いている場合の影響

    • ActionController::LogSubscriber を直接継承・モンキーパッチしていて、internal params の削除ロジックに依存していたコードがある場合は注意が必要です(今回削除されたロジックを前提にしていると挙動が変わる可能性があります)。
    • structured events を自前で listen している場合も、request_started:params は「内部キーがすでに除外された状態の Hash」である、という前提で扱う必要があります。
  • テストへの影響

    • controller のログ出力を検証するテストで、
      • internal params のキーがログに含まれないこと を LogSubscriber の挙動として直接テストしている場合は、いまやその責務は StructuredEventSubscriber 側にあるため、テスト記述の意図を見直した方がよいです。
        ログの最終出力結果を観測するテストであれば、そのままでも動作は変わらないはずです。

  1. 参考情報 (あれば)

#56401 [ci skip] Highlight Subscriber model changes

マージ日: 2026/1/21 | 作成者: @Tretent

  1. 概要 (1-2文で)
    Railsガイド「wishlists.md」の中で、Subscriberモデルに対するコード変更部分にハイライト指定が漏れていた箇所を修正し、他モデルと同様に変更行が強調表示されるようにしたドキュメント専用のPRです。コードや挙動には一切影響せず、ガイドの可読性・一貫性のみを改善しています。

  1. 変更内容の詳細
  • 対象ファイル

    • guides/source/wishlists.md のみ変更(+1 / -1)
  • 背景

    • ガイドのセクション 6.1(wishlists チュートリアルの一部)で、Subscriber モデルに対する変更点を説明しているコード例があるものの、他のモデル(例: User, Article など)の変更例とは異なり、その「変更された行」がハイライトされていなかった。
    • ガイドでは通常、コードブロックの中で「このステップで追加・変更した行」を diff 形式や行番号ハイライトなどで強調しており、読者がどこを編集すべきか一目で分かるようにしている。
  • 実際の変更内容

    • Subscriber モデルのコード例に対し、他のセクションと同じスタイルになるように「新規・変更行のハイライト指定」を1行分追加し、既存の1行を差し替えています(netで +1/-1)。
    • 実コードの変更ではなく、ガイド内のコード例表示用マークアップのみの変更です。

    例(あくまでイメージ):

    diff
    ```ruby
    class Subscriber < ApplicationRecord
    -  has_many :wishlists
    +  has_many :wishlists # ← この行をハイライトする指定を追加
    end
    実際には、Rails ガイド用のハイライト記法(`[6,7]` のような行番号指定、あるいは `diff` 記法)で指定しているはずで、その形式を他のモデルの例と揃えた形です。

  1. 影響範囲・注意点
  • 影響範囲

    • Rails本体のコード、API、挙動には一切影響ありません。
    • 影響するのは ガイド(guides.rubyonrails.org などで公開されるドキュメント)の表示のみ です。
    • 特に、wishlists チュートリアルを読んでいる人にとって、Subscriber モデルの「どこを編集すべきか」が視覚的に分かりやすくなります。
  • 注意点

    • アプリケーションコードの更新や、バージョンアップ時のマイグレーション対応などは不要です。
    • CHANGELOG にも記載なし(ドキュメントのみの変更として扱われています)。
    • もし独自翻訳や社内用に Rails ガイドをミラーしている場合は、この差分を取り込むことで、原文ガイドと表示の一貫性が保たれます。

  1. 参考情報 (あれば)
  • PRメタ情報

    • タイトル: [ci skip] Highlight Subscriber model changes
    • 番号: #56401
    • 作成者: Tretent
    • マージ日時: 2026-01-21T05:05:39Z
    • 内容: ドキュメント(ガイド)のみの変更、CI不要指定([ci skip]
  • 関連する観点

    • Railsガイドでは、学習者が「どの行を追加・変更したのか」をすぐ把握できるように、コードブロックのハイライトを統一的に使っているため、今回のPRはその一貫性を保つためのメンテナンスに位置づけられます。

#56651 Fix comment doc in ActionText::Attachable [ci skip]

マージ日: 2026/1/21 | 作成者: @OutlawAndy

  1. 概要 (1-2文で)
    Action Text の ActionText::Attachable モジュール内にある to_editor_content_attachment_partial_path のコメントドキュメント(サンプルコード)が、実装と食い違っていたため、それを修正するドキュメント専用の PR です。コードの挙動自体は変わっておらず、コメント上の例示だけが正しい形に揃えられています。

  1. 変更内容の詳細
  • 対象: actiontext/lib/action_text/attachable.rb
  • 内容: to_editor_content_attachment_partial_path メソッドの上に記載されているコメント(YARD 形式 / RDoc 形式のドキュメント)中の「使用例コード」を実装に合わせて修正。

ActionText::Attachable は、独自オブジェクトをリッチテキストに添付可能にするためのインターフェイスで、以下のようなメソッドを実装できるモジュールです:

  • to_trix_content_attachment_partial_path
  • to_trix_content_attachment_attributes
  • to_editor_content_attachment_partial_path ← 今回コメントが修正されたメソッド
  • to_editor_content_attachment_attributes

今回の PR は、そのうち to_editor_content_attachment_partial_path のサンプルコードの誤りを修正したものです。
具体的には、例えば以下のようなズレが直されていると考えられます(イメージ):

  • def to_trix_content_attachment_partial_path など別メソッド名になっていた
  • 返却するパスが Action Text の期待する形式になっていなかった
  • 引数や利用側の呼び出し例が古い API のままだった

実装コードは一切変更されておらず、コメント行の追加・修正のみ(+3/-1 行)です。


  1. 影響範囲・注意点
  • ランタイム挙動: 一切変化なし
    • テストや互換性への影響もなし
  • 影響するもの:
    • ActionText::Attachable を読みながら「エディタ側(特に to_editor_content_attachment_* 系)を独自実装している・しようとしている」開発者向けドキュメント
  • 注意点:
    • これまで誤ったコメント例を参考に独自の attachable を実装していた場合、サンプルとの違いが出る可能性があります。今後はこの修正後コメントを参考にするのが安全です。
    • CHANGELOG の更新はなく、公式には「挙動変更なしのドキュメント修正」とみなされます。

  1. 参考情報 (あれば)
  • 対象クラス: ActionText::Attachable
    • 主な用途: モデルや PORO を Action Text の添付オブジェクトとして扱うためのプロトコル提供
  • 関連メソッド(周辺 API を確認したいときに見るとよいもの):
    • to_trix_content_attachment_partial_path
    • to_trix_content_attachment_attributes
    • to_editor_content_attachment_partial_path
    • to_editor_content_attachment_attributes
  • 実際にカスタム attachable を作るときは、最新版の Rails のソース内コメントと edge guides を併せて参照すると、エディタ用のパーシャル構成を誤りにくくなります。

#56647 Load minitest server plugin to run minitest with --bisect option

マージ日: 2026/1/20 | 作成者: @yahonda

  1. 概要 (1-2文で)
    Rails のテストランナーが、Minitest 6 の --bisect オプションを正しく使えるように、Minitest の server プラグインを明示的にロードする変更です。これにより、minitest_bisect 使用時に発生していた invalid option: --server エラーが解消されます。

  1. 変更内容の詳細

背景

  • Minitest 6 では minitest-bisect が本体に同梱されましたが、Minitest 6 以降は「プラグインは opt-in(明示的にロードしないと有効にならない)」という方針になっています。

  • minitest_bisect コマンドは、内部的に Minitest の server プラグイン(--server オプションを提供するプラグイン)に依存しています。

  • しかし、Rails 側ではそのプラグインがロードされていなかったため、--bisect 実行時に Minitest から invalid option: --server が投げられていました(#56642)。

実際の変更

  • 変更ファイル: activesupport/lib/active_support/testing/autorun.rb
  • 変更行数: 1行追加

Rails のテストオートランのセットアップ処理のどこかで、以下のように「Minitest server プラグイン」を読み込む 1 行が追加されたと考えられます(実際のコードは PR 本文にないため、擬似コードですが、イメージとしてはこのような形になります):

ruby
# activesupport/lib/active_support/testing/autorun.rb のどこか
require "minitest/server"  # ← この 1 行が追加された

もしくは Minitest のプラグインロード規約に従い、

ruby
require "minitest/autorun"
require "minitest/server"  # server プラグインを明示的に有効化する

といった形です。

これにより、Rails のテスト環境から Minitest を起動した際に、--server オプションを理解できるようになります。

動作確認の内容

PR の説明にある通り、Active Record/arel/adapter など大量のテストファイルを対象に、PostgreSQL 接続 (ARCONN=postgresql) で以下のように minitest + --bisect を実行しています:

bash
MTB_VERBOSE=2 ARCONN=postgresql \
  bundle exec minitest [大量の test ファイル ...] --bisect --seed 7149

内部で実際に走っているコマンドを見ると:

bash
ruby -Itest:lib -e 'require "...(大量の require)..."' -- --seed 7149 --server 21091

とあり、--server 21091 が Minitest に渡されています。
今回の変更により、--server オプションが正しく解釈され、reproducing...Using postgresql というログのあと、全テストが正常終了しています。

  • テスト結果: 10127 runs, 34634 assertions, 0 failures, 0 errors, 24 skips
  • 最後に「Reproduction run passed? Aborting.」と出ているのは、minitest-bisect 的には「再実行では失敗が再現しなかったので、犯人テストは特定できない」という意味であり、機能としては正常に動作していることを示しています。

  1. 影響範囲・注意点

影響範囲

  • Rails 内部・外部を問わず、ActiveSupport の autorun を通じて Minitest を実行している環境で、Minitest server プラグインが常に読み込まれるようになります。
  • これにより、以下が改善されます:
    • Rails リポジトリ自身の CI/ローカル開発で minitest_bisect を利用して order-dependent テストを切り分けできる。
    • Rails アプリや gem が bundle exec minitest ... --bisect を使ったときにも、invalid option: --server が出ずに動くようになる(ActiveSupport の autorun を経由していれば)。

注意点

  • この PR 自体は 1 行追加のみで、副作用は極めて限定的です。
  • Minitest server プラグイン自体は Minitest 本家で提供されている正式機能であり、ロードするだけで既存のテスト挙動が変わることは基本的にありません(--server を指定しない限り、従来通り)。
  • バグ修正ではありますが、テストコードは追加されていません。そのため、今後 Minitest 側の仕様変更があった際に、--server/bisect 周りの手動確認・回帰に注意が必要です。

  1. 参考情報 (あれば)

まとめると、「Minitest 6 からプラグインが自動では有効にならなくなったため、Rails 側で server プラグインを明示的にロードし、minitest_bisect--bisect)が Rails 環境でもきちんと動くようにした PR」です。


#56645 [8-1-stable] Handle Ruby 4.1 stabby lambda in Proc#source_location start_column

マージ日: 2026/1/19 | 作成者: @zzak

  1. 概要 (1-2文で)
    Rails 8.1 系のテスト用アサーションが、Ruby 4.1 における「stabby lambda(->)」の Proc#source_location / start_column の挙動に対応するためのバックポートです。8-1-stable ブランチに、既に main 側に入っている修正 (#56624) を取り込んでいます。

  1. 変更内容の詳細
  • 対象ファイル:
    activesupport/lib/active_support/testing/assertions.rb に 3 行のコードが追加されています(削除はなし)。

  • 背景となる Ruby 側の変更イメージ
    Ruby 4.1 では、「stabby lambda(->)」で定義された Procsource_location および start_column の扱いが従来と微妙に変わっています。具体的には、以下のようなコードでカラム位置(start_column)が、-> の始点やブロック本体の始点をどのように数えるかが変わる、あるいは Ruby 側で明示的にサポートされるようになったと考えられます。

    ruby
    l = ->(x) { x + 1 }
    # Ruby 4.1 で l.source_location や l.start_column が変わる / 追加される
    
    p l.source_location  # => ["path/to/file.rb", line_number]
    p l.start_column     # => カラム番号(Ruby 4.1 で安定して取得できる)
  • Rails 側の対応内容(推測ベースの解説)
    ActiveSupport のテスト関連アサーションは、ブロックや Proc の定義位置を検査するために Proc#source_locationstart_column を用いています。
    Ruby 4.1 で stabby lambda のカラム位置が変わったことにより、「テストが Ruby 4.1 だとだけ落ちる」ような状況が発生し得るため、その差異を吸収するロジックが assertions.rb に追加されたと考えられます。

    典型的には以下のような処理が行われます:

    • Proc#source_location が返す「行・列」の情報に対して、
      • Ruby 4.1 では stabby lambda の場合にだけずれる/変わる挙動を検出し、
      • それを補正する、あるいは
      • 旧バージョン / 新バージョンのどちらでも同じように通るよう「比較のしかた」を緩和する(例: カラム位置を厳密に比較しない)
        といった互換性用のコードが 3 行分追加されています。

    コード例のイメージ(実際のコードではないサンプル):

    ruby
    # 例: カラム情報が存在しない / Ruby 4.1 の stabby lambda で差がある場合に備えて
    line, column = proc.source_location
    column ||= 0  # カラム情報がない場合でも落ちないようにする
    
    # もしくは Ruby バージョンや lambda の形式によって扱いを変える
    if RUBY_VERSION >= "4.1" && proc.lambda?
      # stabby lambda の start_column 仕様に対応したロジック
    end

    実際には、3行という非常に小さな修正のため、

    • 「start_column メソッドがあるかどうかを safe-navigation で見る」
    • 「nil の場合のデフォルト値を足す」
      など、最小限の互換性コードである可能性が高いです。

  1. 影響範囲・注意点
  • 影響範囲

    • ActiveSupport のテストアサーション(ActiveSupport::Testing::Assertions)を利用するコード、とくに「ブロック / Proc の定義位置・ソース位置」をテストするような箇所に影響します。
    • 実運用アプリケーションの本番動作への影響はほぼありません。テストに限定される変更です。
    • Ruby 4.1 を使って Rails 8.1 を動かしている(あるいは動かす予定の)環境で、テストが安定して動くようになる修正です。
  • 注意点

    • Ruby 3.x 以前のバージョンでは、今回の変更は後方互換を壊さないように実装されていると考えられますが、もし自前で Proc#source_locationstart_column を直接扱う独自アサーション・メタプログラミングをしている場合は、自分のコード側でも Ruby 4.1 の挙動差を確認しておくと安全です。
    • CI で Ruby 4.1 を追加する場合、本PRが入っていない古い 8.1 のコミットを使っていると、テスト結果が Ruby バージョンによって揺れる可能性があります。この PR が入った 8-1-stable 以降を使うことが推奨されます。

  1. 参考情報 (あれば)
  • 元 PR(main / master 向けのオリジナル修正):
    • #56624 — Ruby 4.1 の stabby lambda における Proc#source_location / start_column への対応本体
  • バックポート PR:
    • #56645 — 本件(8-1-stable へのバックポート)
  • Ruby 側の関連仕様:
    • Proc#source_location: ["file.rb", line_number] の配列を返すメソッド
    • Proc#start_column: Proc 定義の開始カラムを返すメソッド(Ruby 3.4 以降〜4.x 系で拡張されている領域)
  • より詳細な差分や実際の 3 行のコード内容については、GitHub 上の PR #56624 / #56645 の diff を直接参照するのが確実です。

#56644 [8-0-stable] Handle Ruby 4.1 stabby lambda in Proc#source_location start_column

マージ日: 2026/1/19 | 作成者: @zzak

  1. 概要 (1-2文で)
    Ruby 4.1 で導入される stabby lambda (-> {} 形式) に対して、Proc#source_location が返す「開始カラム(start_column)」の扱いをテスト側で正しく解釈できるようにする修正を、Rails 8.0 の安定ブランチへバックポートした PR です。ActiveSupport のテスト用アサーション(ActiveSupport::Testing::Assertions)に、Ruby 4.1 向けの対応が追加されています。

  1. 変更内容の詳細

どのファイルが変わったか

  • activesupport/lib/active_support/testing/assertions.rb に 3 行追加

Rails 本体のロジックというより、「テスト用アサーション」が Ruby 4.1 の Proc#source_location 挙動に追随するための調整です。元 PR (#56624) のバックポートなので、主な意図は以下です。

意図している問題領域

Ruby 3.2 以降で Proc#source_location が行番号だけでなくカラム情報も含むようになり、さらに Ruby 4.1 では stabby lambda (->(x) { ... }) に対しても「どこから始まるか(start_column)」の扱いが変わる/厳密になるため、テストで

  • ブロック(proc / lambda / -> など)の開始位置
  • エラー発生箇所の位置情報

を検証しているコードが、Ruby のバージョンによって微妙にズレる可能性があります。

ActiveSupport の testing/assertions.rb には、例外のバックトレースやブロックの定義位置を扱うためのアサーションがあり、その内部で Proc#source_location を利用しています。この PR では、stabby lambda の場合でも Ruby 4.1 の仕様に沿ってカラム位置を正しく扱うような分岐/調整が 3 行だけ追加されています。

元 PR (#56624) でやっている内容(推測される形)としては、例えば以下のようなパターンが想定されます:

ruby
# 例: Ruby 4.1 + stabby lambda でのソース位置取得
pr = ->(x) { x * 2 }
file, line, column = pr.source_location # Ruby 側がカラム情報を返す or 専用 API 経由

# ActiveSupport 側では、Ruby 4.1 の stabby lambda のカラム値を考慮して
# アサーション用に位置を扱う

追加された 3 行は、おそらく以下のどれか(または組み合わせ)です。

  • Ruby のバージョンや Proc の形(-> かどうか)を判別して、カラム値の補正を行う
  • stabby lambda のときだけ、start_column の扱い方を切り替える
  • 古い Ruby でも動くように respond_to? ガードを入れている

いずれにせよ、アサーション内部の「位置情報の扱い」の分岐が増えただけで、アプリケーションコードの実行パスには入らない変更です。


  1. 影響範囲・注意点
  • 影響範囲

    • 主に Rails のテスト実行時 に使われる ActiveSupport のアサーションに限られます。
    • Ruby 4.1(または同等の Proc#source_location 仕様)で Rails のテストスイートを動かしたときに、stabby lambda を使用している箇所の位置情報に依存したテストが安定して動作するようになります。
    • アプリケーション本番コードの挙動にはほぼ影響しません。
  • 注意点

    • この変更は Ruby 4.1 対応の一部であり、Ruby 4.1 で Rails 8.0 を使う際のテスト互換性向上 が主な目的です。
    • すでに Ruby 3.x で問題なくテストが通っている場合、今回のパッチによる挙動の違いは基本的にありません(あっても位置情報の扱い程度)。
    • 独自に Proc#source_location や Ruby のカラム情報を使っているテストヘルパーを書いている場合、Ruby 4.1 でのカラム値の変化を考慮する必要があるかもしれませんが、この PR 自体はそのための「Rails 標準アサーション側の追随」に留まります。

  1. 参考情報 (あれば)
  • 元 PR: #56624
    • 今回の変更の本体。Ruby 4.1 の stabby lambda 対応がどのように実装されたかを確認できます。
  • 対象 PR: #56644
    • 本 PR(8-0-stable ブランチへのバックポート)。
  • 関連 Ruby 機能
    • Proc#source_location と、Ruby 3.2+ のカラム情報サポート
    • stabby lambda 構文: ->(args) { body }

#56624 Handle Ruby 4.1 stabby lambda in Proc#source_location start_column

マージ日: 2026/1/19 | 作成者: @zzak

  1. 概要 (1-2文で)
    Ruby 4.1 で ->(stabby lambda)の Proc#source_location のカラム位置が変わったことで、Rails のテスト用アサーションメッセージが壊れていた問題を回避する修正です。assert_changes / assert_no_changes / assert_difference などで、ブロックとして渡された lambda の「本体だけ」を従来通り表示できるようにしています。

  1. 変更内容の詳細

問題の背景

Ruby 4.1 で以下のような変更が入りました(Ruby 本体側の意図した仕様変更):

ruby
-> { @object.num }

に対する Proc#source_location の「開始カラム」が、lambda 本体の { ではなく「-> を含む lambda 全体の定義開始位置」を指すようになりました(c970d2941d56a862... のコミット)。
Rails は Proc#source_location と元ファイルのソースコードから、ブロック/ lambda の「式部分」だけを抜き出して assertion メッセージに表示していますが、この開始位置のズレにより、メッセージ中に期待していた @object.num ではなく、#<Proc:0x...> のような Proc#inspect の出力が使われてしまう形になっていました。

その結果、例えば次のようなテストが失敗します:

ruby
assert_no_changes -> { @object.num } do
  # ...
end

期待されるメッセージ:

text
"`@object.num` changed.
Expected: 0
  Actual: 1"

実際のメッセージ(Ruby 4.1 + 変更前 Rails):

text
"`#<Proc:0xXXXXXX /path/to/test_case_test.rb:381 (lambda)>` changed.
Expected: 0
  Actual: 1"

同様の崩れが assert_difference / assert_changes など、lambda を取るアサーションで連鎖的に発生していました。

PR で行ったこと

activesupport/lib/active_support/testing/assertions.rb に、Ruby 4.1 の stabby lambda による source_location の変化を吸収する処理を追加しています。

要点:

  • テスト用アサーションが「lambda の本体だけを表示したい」という前提は変えない。
  • Ruby 4.1 では Proc#source_location から取得したコードフラグメントに -> などの「stabby lambda の構文部分」が含まれてしまうので、それを「文字列として strip する」ことで従来通りの表示に戻す。
  • 本体の式(例: @object.num)だけを抜き出すように調整。

PR の説明にある通り:

Since the goal here is to only display the body of the lambda, we can strip the stabby part and things should Just Work.

コードのざっくりしたイメージ(実際の実装のニュアンスレベル)としては:

ruby
def extract_expression_from_proc(proc)
  file, line = proc.source_location
  source = File.read(file).lines[line - 1]

  # ここで Ruby 4.1 から含まれるようになった "->" 部分などを取り除き
  # lambda 本体の式だけを抽出するような処理を追加
  source = strip_stabby_lambda_syntax(source)

  source.strip
end

実際には 3 行程度の小さな変更で、-> など stabby lambda を検知・削除する処理が追加されていると考えてよいです。

これにより、Ruby 4.1 でも以下のように、従来通り本体のみがメッセージに出るようになります:

text
"`@object.num` didn't change by 1, but by 0.
Expected: 1
  Actual: 0"

  1. 影響範囲・注意点
  • 影響範囲
    • ActiveSupport のテストアサーション:
      • assert_changes
      • assert_no_changes
      • assert_difference など、lambda / Proc を引数に取り、その中身をメッセージとして表示するアサーション。
    • これらを stabby lambda (-> { ... }) で使っている場合 に Ruby 4.1 で崩れていたメッセージが修正されます。
  • 挙動の変化
    • メッセージ中に #<Proc:0xXXXXXX ...> のような Proc#inspect が出ていたものが、@object.num などの式本体だけになる(Ruby 3.x までと同じ体感挙動)。
  • 互換性
    • Ruby 4.1 以前のバージョンにも後方互換的に動くような形の変更であり、既存テストが通る範囲での微調整なので、通常の Rails アプリケーションコードへの影響はほぼありません。
    • もし自前で ActiveSupport の同アサーションを monkey patch している場合は、今回の Proc からの式抽出の仕様を前提にしていないか確認した方が安全です。
  • 注意点
    • PR が想定しているのは Ruby 本体の仕様変更へのワークアラウンドであり、Ruby 側で挙動が再度変わった場合は、さらに調整が必要になる可能性があります。
    • メッセージ生成において「ソースコードをファイルから読み直す」アプローチ自体は変わっていないため、eval されたコードや標準入力経由のコードなど、ファイルに実体がない Proc については引き続き正しく扱えないケースがあります(従来と同じ制限)。

  1. 参考情報 (あれば)

#56631 Remove dead compatibility code with ripper

マージ日: 2026/1/18 | 作成者: @Earlopain

  1. 概要 (1-2文で)
    Rails の Ruby 要求バージョンが 3.3 になり、標準で Prism が入る前提になったため、ripper ベースの互換コードを削除し、ソース解析・テンプレート依存関係解析などを Prism 前提の実装に整理した PR です。
    これによりコード量が大きく削減され、パーサ周りの分岐・互換レイヤがシンプルになっています。

  1. 変更内容の詳細

全体方針

  • 旧来の Ripper ベースのコードと、「Prism があれば Prism を使い、なければ Ripper」というような互換処理をすべて廃止。
  • Rails 7.2(想定)以降は Ruby 3.3 以上を前提にし、常に Prism ベースでソースコード解析・テンプレート依存関係解析・テストパーサを動かす設計に変更。

2-1. Action View: 依存関係トラッカーとレンダーパ―サ

対象ファイル:

  • actionview/lib/action_view/dependency_tracker/ruby_tracker.rb
  • actionview/lib/action_view/render_parser.rb
  • actionview/lib/action_view/render_parser/prism_render_parser.rb (削除)
  • actionview/lib/action_view/render_parser/ripper_render_parser.rb (削除)
  • actionview/test/template/dependency_tracker_test.rb

主な変更点:

  1. PrismRenderParser / RipperRenderParser クラスの削除

    • 以前は ActionView::RenderParser に対して、Prism 実装・Ripper 実装が別ファイルで定義され、Ruby バージョンや環境に応じてどちらかを使う構造だったものを削除。
    • render_parser.rb 内に Prism ベースの実装を統合する形に変更されています(+144/-25 行から、Prism 相当のロジックがここに移されたと推測できます)。
  2. ruby_tracker.rb の単純化

    • テンプレートの依存関係解析 (render 呼び出しのトラッキングなど) で利用される Ruby コードパーサが、Prism 前提のものだけを想定するように整理。
    • 「Prism が利用可能なら Prism、それ以外は Ripper」というような条件分岐が削除されているはずです。
  3. テストコードの更新 (dependency_tracker_test.rb)

    • Ripper を前提としたテストケースや、実装切り替えに関するテストが削除・変更。
    • Prism 専用の挙動を前提としたテストだけに整理され、テストコードの行数もかなり減っています(+4/-25)。

イメージ例 (概念レベル)

従来(イメージ):

ruby
# render_parser.rb
if defined?(Prism)
  require "action_view/render_parser/prism_render_parser"
else
  require "action_view/render_parser/ripper_render_parser"
end

今回以降(イメージ):

ruby
# render_parser.rb
# Ruby 3.3 以上前提なので Prism 一択
# Prism を前提とした実装をこのファイル内に直接記述
class ActionView::RenderParser
  # Prism によるパース実装
end

このように、Prism/Ripper の二重実装とスイッチング処理がなくなり、Prism のみを前提にしたクラス構造になっています。


2-2. Railties: コメント抽出・テスト用パーサ

対象ファイル:

  • railties/lib/rails/source_annotation_extractor.rb
  • railties/lib/rails/test_unit/test_parser.rb

source_annotation_extractor.rb の変更

  • rake notes などで使われる「コメント中の TODO/FIXME などを抽出する機能」の内部で、Ruby コードをパースして行番号や位置を取得する部分から Ripper 互換コードを削除。
  • Ruby 3.3 以降に含まれる Prism を利用して、コメントを含めたソースコードの位置情報を取る実装に一本化。
  • Ripper を使うか Prism を使うかを切り替える条件分岐がなくなり、実装が 6 行追加 / 34 行削除と大幅に簡潔化されています。

test_parser.rb の変更

  • Rails のテストフレームワーク (rails test) がテストファイル中の test "..." do などを解析するために使う テストパーサが、Ripper ベースから Prism ベースに完全移行。
  • 以前は Ripper クラスを拡張して on_method_add_block などのコールバックを拾い、テスト定義の AST を組み立てていたものが、Prism の AST ノードを前提にテストの検出・情報抽出を行うよう書き換えられています。
  • コード量が 24 行追加 / 122 行削除となっており、こちらも互換レイヤを捨ててシンプルな Prism 前提実装にリファクタされています。

イメージ(かなり単純化したダミー例)

従来(Ripper イメージ):

ruby
class TestParser < Ripper::SexpBuilder
  def on_method_add_block(call, block)
    if call_is_minitest_test_method?(call)
      register_test(block)
    end
  end
end

今回以降(Prism イメージ):

ruby
class TestParser
  def initialize(source)
    @tree = Prism.parse(source)
  end

  def each_test
    walk(@tree) do |node|
      if minitest_test_block?(node)
        yield build_test_from(node)
      end
    end
  end
end

  1. 影響範囲・注意点

  2. Ruby 3.3 未満は完全に非対応

    • この PR 自体の前提として、Rails は Ruby 3.3 以上必須になっています。
    • 「Ruby 3.2 + Prism gem を手動で入れて動かす」といった構成はサポートの対象外になり、コード上の fallback もなくなりました。
  3. Ripper 拡張に依存していた独自コードへの影響(間接的)

    • Rails 本体は Ripper を使わなくなりましたが、自前で Ripper を拡張して Rails 内部の挙動(特に test_parser / source_annotation_extractor / ActionView::RenderParser)にフックしていた場合、当然ながらそのフックは動かなくなります。
    • 例えば「Rails の test parser を差し替えて独自 DSL をサポートしていた」といった場合は、Prism AST ベースの実装に追従する必要があります。
  4. パーサの挙動差による微妙な影響の可能性

    • Prism と Ripper では、コメントやヒアドキュメント、キーワード引数などの細かい扱いが異なることがあります。
    • 依存関係トラッカー(render 呼び出しの検出など)や rake notes のコメント抽出が、ごく一部の特殊な Ruby 構文で以前と違う結果を返す可能性はあります。
    • ただし Ruby 本体側も Prism に注力しており、今後はこちらの方が安定していく見込みです。
  5. テスト/ツールのメンテナンス性向上

    • Rails コアとしては、Prism 一択になったことでパーサ関連のバグ修正・最適化がかなりやりやすくなります。
    • 対応すべき Ruby バージョンが Ruby 3.3+ だけになり、分岐や条件付きテストを減らせるため、将来的な保守性・パフォーマンス面のメリットが期待できます。

  1. 参考情報 (あれば)

この PR は「新機能追加」というより、「サポート範囲の明確化(Ruby 3.3 以上)と、それに伴う互換コードの掃除・Prism ベースへの一本化」という性格が強い変更です。


#56628 Fix outdated ActiveRecord finder docs. [ci skip]

マージ日: 2026/1/18 | 作成者: @mdh

  1. 概要 (1-2文で)
    ActiveRecord::FinderMethods のドキュメントに残っていた古い where の配列形式の記法を、現在推奨されるハッシュ記法に統一した PR です。コードの挙動変更はなく、ドキュメントのみの更新です。

  1. 変更内容の詳細 (サンプルコード含む)

対象:

  • activerecord/lib/active_record/relation/finder_methods.rb 内の YARD コメント・サンプルコード

主な変更点:

  • where に対する「(ネストした)配列を使った条件指定」の例を削除・修正し、ハッシュ(暗黙ハッシュも含む)記法へ書き換えています。
  • これにより、ドキュメントが現在の Rails の推奨スタイルと整合するようになっています。

典型的に、次のような旧来の書き方が例示されていた部分が:

ruby
# 旧: 配列形式の例(イメージ)
where(["name = ? AND status = ?", "David", "active"])
where(["users.name = ? AND accounts.enabled = ?", "David", true])

現在推奨されるハッシュ形式へと書き換えられています:

ruby
# 新: ハッシュ形式の例(イメージ)
where(name: "David", status: "active")
where(users: { name: "David" }, accounts: { enabled: true })

また、ネストした条件を示す例も、次のようにより宣言的なスタイルが前面に出るようになっていると考えられます:

ruby
# 旧例(ネスト配列)
where(["posts.published_at >= ? AND comments.approved = ?", 1.week.ago, true])

# 新例(ネストハッシュ)
where(posts: { published_at: 1.week.ago }, comments: { approved: true })

※実際の diff では行数的に 11 行追加・11 行削除で、こうしたサンプルをハッシュ記法へ統一する変更がなされています。


  1. 影響範囲・注意点
  • 実行時挙動への影響

    • ライブラリコード本体には手を加えておらず、コメント(ドキュメント)のみの変更です。既存アプリケーションの挙動には一切影響しません。
  • 開発者への影響

    • Rails ガイドや API ドキュメントを見ながら where を書く初学者・中級者が、古い配列形式に誘導されにくくなります。
    • 「配列形式が廃止された」わけではなく、現時点の推奨スタイルがハッシュ記法であることがより明示されたという位置づけです。
    • 既に配列形式を現場で使っているコードを、ただちに書き換える必要はありませんが、新規コードやリファクタ時にはハッシュ記法を優先すると、ドキュメント/コミュニティの慣習と揃えやすくなります。
  • ドキュメントとの整合性

    • Active Record の他の部分や Rails ガイドで既に主流となっている書き方と整合が取られたため、情報の断片ごとにスタイルがずれる、という問題が軽減されます。

  1. 参考情報 (あれば)
  • 対象クラス:
    • ActiveRecord::FinderMethods
      • where, first, last, take など、レコード検索周りのメソッド群を提供するモジュール
  • 関連する記法の一般的な推奨:
    • シンプルな等価条件や JOIN されたテーブルの条件には、ハッシュまたはネストハッシュ:
      ruby
      where(status: "active")
      where(articles: { published: true })
    • 生の SQL フラグメントや複雑な条件は Arel / スコープ / メソッド抽出を利用:
      ruby
      where(Article.arel_table[:views].gt(100))
      # または
      scope :popular, -> { where(Article.arel_table[:views].gt(100)) }
  • PR 番号: #56628
    • タイトルにも [ci skip] が付いている通り、CI を必要としない純ドキュメント変更として扱われています。

#56639 Console reload! will reset the console's executor, when present

マージ日: 2026/1/18 | 作成者: @bensheldon

  1. 概要 (1-2文で)
    Rails コンソールで reload! を実行したときに、コンソール用にラップされている Executor(スレッドローカルなどの実行コンテキストを管理する仕組み)もリセットされるようになりました。これにより、長時間同じコンソールセッションを使い続けた際の Executor 周りの状態を簡単にリフレッシュできるようになります。

  1. 変更内容の詳細

背景

  • #56297 で「Rails コンソールを Executor でラップする」変更が入ったことで、コンソールの実行が ActiveSupport::Executor の管理下に入りました。
  • その副作用として、クエリキャッシュが暗黙に有効になる (#56473) など、「コンソールを立ち上げてから終了するまで Executor の状態がずっと持続する」ことによる影響が発生していました。
  • コンソールはしばしば長時間同じセッションを開きっぱなしで使うため、「Executor のライフサイクルを途中でリセットしたい」というニーズがあります。
  • コンソール利用者がよく使う「状態リセットに相当するもの」は reload! であるため、reload! 実行時に Executor もリセットする挙動を追加した、というのがこの PR の趣旨です。

実際の変更点

変更ファイルは以下の4つです。

  • railties/lib/rails/commands/console/irb_console.rb
  • activesupport/test/executor_test.rb
  • railties/test/application/console_test.rb
  • railties/CHANGELOG.md

コンソール側 (irb_console.rb)

reload! コマンドの実装に、「Executor をリセットする」処理が加わりました。

概念的には以下のような流れになります(疑似コード):

ruby
# コンソール内で reload! が呼ばれたとき

def reload!
  # 既存: アプリケーションコードのリロード
  app.reload!

  # 新規: コンソール用 Executor のリセット
  if defined?(Rails.application.executor)
    Rails.application.executor.reset # 実際は executor の API に合わせた呼び出し
  end

  true
end

※実際のメソッド名は Rails 内部 API に合わせた呼び出しになっているはずですが、PR 要約レベルでは「reload! の中で Executor のリセット API を叩いている」と理解すれば十分です。

Executor のテスト (activesupport/test/executor_test.rb)

Executor のリセット動作に関するテストが追加されています。
ここでは、Executor をリセットしたときに

  • スレッドローカルな状態やランタイムのフック類が適切にクリアされる
  • その後の実行が新しいコンテキストで行われる

といった性質が保証されるようになっています。

コンソールのテスト (railties/test/application/console_test.rb)

コンソールから reload! を呼び出したときに、Executor のリセットが行われることを確認するテストが追加されています。
テストでは、概ね次のようなことが検証されていると考えられます:

  • コンソール起動 → Executor がコンソールセッションに紐づく
  • reload! を実行
  • Executor の状態がリセットされたことを示す何らかの指標(例: スレッドローカル変数がクリアされる、特定のフックが再設定される 等)をアサート

CHANGELOG (railties/CHANGELOG.md)

railties の CHANGELOG に以下のような内容が追加されています(要旨):

  • Rails コンソールにおいて reload! を実行すると、コンソールで使用している Executor もリセットされるようになった。

これにより、ドキュメント的にも「reload! は Executor もリセットする」という仕様が明示されました。


  1. 影響範囲・注意点

影響範囲

  • 対象: Rails コンソール (rails console) 使用時のみ
  • 変更点:
    • これまで reload! は「コードのリロード」中心の挙動だったのに対し、今後は「Executor が持っている各種状態(スレッドローカル、クエリキャッシュの状態等)」も合わせてリセットされます。

そのため、長時間コンソールを使っていて、Executor に依存する状態を保持していたコード(例えば middleware 的なフック、スレッドローカルを使ったトレーシング/ロギングなど)がある場合、

  • reload! 実行後には、それらの状態がクリアされる
  • 必要な初期化処理があれば、再度セットアップを行う必要がある

という動作になります。

注意点

  • reload! の名称から「コードの再読み込み + Executor リセット」を期待できるのは自然ですが、PR 内でも触れられているように「Executor の再起動そのものはコードリロードを引き起こさない」ことに注意が必要です。
    • あくまで「reload! がコードリロードを行い、そのタイミングで Executor もリセットする」のであって、
    • 「Executor をリセットすればコードがリロードされる」わけではありません。
  • クエリキャッシュなど、Executor のライフサイクルに依存する機能を調査・デバッグするときには、
    • セッションを終了して立ち上げ直す代わりに reload! を使うことで、
    • ランタイム状態を手軽にリセットできるようになりますが、
    • 一方で「reload! 後も Executor の状態が保持されている」ことを前提にしたテスト的な使い方は成立しなくなります。

  1. 参考情報 (あれば)
  • 関連 PR:
    • #56297: Console を Executor でラップした変更
    • #56473: Executor による Query Cache 暗黙有効化の指摘
  • キーワード:
    • ActiveSupport::Executor
    • Rails console (rails console)
    • reload!(コードリロード + Executor リセット)
    • Query Cache / スレッドローカルな状態管理

#56629 Deprecate queue_classic Active Job adapter

マージ日: 2026/1/16 | 作成者: @morgoth

  1. 概要 (1-2文で)
    Rails の Active Job が提供していた queue_classic アダプタが「非推奨(deprecated)」としてマークされました。queue_classic は事実上メンテナンスが止まっており、今後 Rails 本体から取り除かれる方向であることが明示されています。

  1. 変更内容の詳細

a. Active Job CHANGELOG の更新

activejob/CHANGELOG.md に、queue_classic アダプタの非推奨化についてのエントリが追加されています。
これにより、「このバージョンから queue_classic アダプタは deprecated です」という公式な記録が残ります。

b. queue_classic アダプタ本体への deprecate 表示追加

activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb に、deprecation の警告を出すためのコードが追加されています。
典型的には、アダプタ使用時に ActiveSupport::Deprecation.warn を通じて警告が出る形です。

おおよそ次のようなイメージの変更が入っていると考えられます(実際のメッセージは多少異なる可能性がありますが、趣旨は同じです):

ruby
module ActiveJob
  module QueueAdapters
    class QueueClassicAdapter
      def initialize(*)
        ActiveSupport::Deprecation.warn(
          "The queue_classic Active Job adapter is deprecated and will be removed in a future Rails version. " \
          "Consider using another Active Job adapter."
        )
        super
      end

      # 既存の enqueue / enqueue_at 実装などはそのまま
    end
  end
end

これにより、config.active_job.queue_adapter = :queue_classic を設定しているアプリでジョブをキューイングする際などに、deprecation 警告がログやテスト出力に現れます。

c. テストコードの追加

activejob/test/cases/adapter_test.rb に、deprecation を検証するテストが追加されています。

たとえば、以下のような観点のテストが含まれていると考えられます:

  • ActiveJob::Base.queue_adapter = :queue_classic を設定したときに deprecation が発生するか
  • perform_later 等を実行したときに deprecation のメッセージが出るか

これにより、「queue_classic アダプタを使った場合、必ず deprecation が通知される」ことがテストで保証されます。


  1. 影響範囲・注意点

対象となるユーザー

  • config.active_job.queue_adapter = :queue_classic を利用している Rails アプリケーション
  • queue_classic を前提としたジョブ基盤を運用しているプロジェクト

直接の影響

  • 今すぐ機能が壊れるわけではありませんが、
    • Rails 実行時やジョブ実行時に deprecation 警告がログに出るようになります。
    • 将来の Rails メジャー/マイナーバージョンで、queue_classic アダプタが削除される可能性が高いです。

実務上の対応

  1. 代替アダプタへの移行を検討する
    よく使われている選択肢:

    • Sidekiq (:sidekiq)
    • Delayed Job (:delayed_job)
    • Resque (:resque)
    • Solid Queue (:solid_queue)(最近の Rails で公式に推されているキュー基盤)
  2. 移行ステップの例

    • まず Active Job のインターフェイス (perform_later, set(wait: ...)) を正しく使っているか確認
      → 直接 queue_classic に依存するコード(QC.enqueue など)がないか洗い出す。
    • 新しいアダプタの導入と設定:
      ruby
      # 例: Sidekiq に移行する場合
      # config/application.rb など
      config.active_job.queue_adapter = :sidekiq
    • 旧ジョブと新ジョブのキューをどう扱うかを検討
      queue_classic に残っているキューをどう捌くか、移行期間を設けるか、など。
  3. 運用上の注意

    • queue_classic 自体の gem が 2 年以上更新されておらず、Rails 側も切り離しに向かっているため、 セキュリティ・互換性の観点からも早めの移行が推奨されます。
    • CI で deprecation をエラー扱いしている場合(DEPRECATION_WARNINGS=fail 的な運用)、 この変更により CI が落ち始める可能性があります。その場合は、
      • 一時的に queue_classic の deprecation を無視する設定を入れる
      • もしくは早めにアダプタ移行を行う
        などの対応が必要です。

  1. 参考情報 (あれば)
  • この PR での前提:
    • queue_classic 本体リポジトリへのアップストリーム PR:
      https://github.com/QueueClassic/queue_classic/pull/354
      → ここで Rails 側のアダプタを gem 本体側に取り込む提案がされていますが、
      2 年間アクティビティがないため事実上止まっている状況です。
  • Rails 側の関連 Issue:
    • Active Job から各種アダプタを段階的に切り出していく流れ:
      https://github.com/rails/rails/issues/52929
    • 今回の PR は「Active Job に同梱されているアダプタを外に出す」施策のうち、
      queue_classic が「最後の一つ」であることが明示されています。

今後の Rails バージョンアップでアダプタ削除が入る可能性が高いため、queue_classic 利用プロジェクトでは中期的な「ジョブ基盤の乗り換え計画」を立てておくのが安全です。


#56625 Report render stream errors to Rails.error

マージ日: 2026/1/16 | 作成者: @byroot

  1. 概要 (1-2文で)
    Railsの「ストリーミングレンダリング (render stream) 中に発生した例外」を、単なるログ出力だけでなく Rails.error に報告するようにしたPRです。これにより、Sentry等のエラー監視ツールがストリーミング中のエラーも拾いやすくなります。

  1. 変更内容の詳細

背景

  • 従来:

    • ストリーミング (render stream: true など) の途中で例外が発生した場合、Railsはログには書くものの、
      • ActionDispatch::ShowExceptions
      • ActionDispatch::DebugExceptions
        にフックしている多くのエラーレポーティングツールには届かない、という問題がありました。
    • そのため、ストリーミング中だけエラー監視から漏れるケースがあった、という issue (#23856) が報告されていました。
  • 現在:

    • Rails には Rails.error という、フレームワーク標準の「エラー報告API」が用意されています。
    • このPRでは、そのAPIをストリーミング用レンダラから呼び出すことで、ストリーミング中の例外も標準的なルートで報告されるようにしています。

主なコード変更ポイント

変更ファイルは2つです:

  1. actionview/lib/action_view/renderer/streaming_template_renderer.rb
  2. actionpack/test/controller/new_base/render_streaming_test.rb

streaming_template_renderer.rb の変更

元々このクラスは、ビューをストリーミングしながらテンプレートをレンダリングする責務を持っており、その過程で例外が出る可能性があります。

このPRで行っているのは概ね以下のようなことです(擬似コードイメージ):

ruby
# 例:ストリーミング処理中のどこか
def render_template(...)
  # ストリーミングでレスポンスを返す処理
  stream.call do
    begin
      # 本来のレンダリング処理
      template.render(...)
    rescue => error
      # 以前はログ出力などにとどまっていた部分で...
      Rails.error.report(error, handled: true, severity: :error, context: { ... })

      # 必要に応じてストリームを閉じるなどの後処理
      stream.close
    end
  end
end

実際のコードでは、

  • 例外の捕捉箇所
  • Rails.error.report に渡すオプション(handled: true かどうか、context情報など)
    が適切に設定された上で、Rails.error を呼び出すように変更されています。

行数的には、単純な追記というより、「例外処理まわりの構造を少し書き換えつつ Rails.error を差し込む」ような変更になっており、
+11 / -12 といった形で入れ替えが行われています。

テスト render_streaming_test.rb の変更

ストリーミング中のエラーが Rails.error に報告されることを検証するテストが追加されています。

イメージとしては以下のような内容です(擬似コード):

ruby
test "reports streaming errors to Rails.error" do
  error_reported = nil

  Rails.error.stub :report, ->(error, **options) { error_reported = [error, options] } do
    get :some_streaming_action # 内部で意図的に例外を発生させる
  end

  assert error_reported
  error, options = error_reported

  assert_kind_of SomeErrorClass, error
  # handled: true など、期待されるオプションが渡されているかを検証
  assert_equal true, options[:handled]
end

このように、

  • ストリーミングアクション実行中に例外を発生させ、
  • Rails.error.report が呼ばれていること、
  • 必要なメタ情報が渡っていること、
    を確認するテストが追加されています。

  1. 影響範囲・注意点

影響範囲

  • 対象となるのはストリーミングレスポンスを使っているコードです。
    • 例:render stream: true などでテンプレートをストリーミングしているアクション。
  • それ以外(通常の非ストリーミングな render)には影響しません。
  • Rails.error にフックしているエラー監視ツール(Sentry, Bugsnag, Honeybadger など)では:
    • これまで検知されていなかった「ストリーミング中の例外」が新たに報告されるようになります。

注意点

  • ログ・アラートの増加
    • これまでログにしか出てこなかったストリーミング中のエラーが、APM / エラーレポーティングサービスにも上がってくるようになるため、
      • デプロイ直後などに「新しいエラーが突然増えた」ように見える可能性があります(実際には今まで見えていなかったもの)。
  • handled フラグやコンテキスト
    • Rails.error.report にどのようなフラグやメタ情報が付与されているかによって、
      • ツール側で「通知対象にするか」「サンプリングの扱いをどうするか」などが変わる場合があります。
    • 利用中のエラーツールで handled: true/false 等に基づくフィルタリングを行っている場合は、挙動の変化に注意してください。
  • ストリーミングの中断・例外ハンドリング自体の挙動(レスポンス内容など)は、このPRの主眼ではなく、主に「レポート先を増やす」変更です。
    • クライアント側の見え方(途中で接続が切れる・不正なHTMLで終わる等)は従来と基本的に同じと考えられます。

  1. 参考情報 (あれば)
  • 関連Issue:
  • Rails.error について:
    • Rails 7.1 以降で導入された、標準化されたエラー報告APIです。
    • 代表的な使い方(参考):
      ruby
      Rails.error.report(exception, handled: true, severity: :error, context: { user_id: current_user&.id })
    • ミドルウェアの例外ハンドリングに依存せず、「任意の場所からエラーを送信できる」ため、今回のようなストリーミング処理やバックグラウンド処理との相性が良いです。

#56626 Optimize String#squish

マージ日: 2026/1/16 | 作成者: @byroot

  1. 概要 (1-2文で)
    String#squish の内部実装で使っている正規表現を変更し、単一の半角スペース " " にはマッチしないようにすることで、実行頻度の高いケースでのパフォーマンスを大幅に改善した PR です。計測例では約 2 倍高速になっています。

  1. 変更内容の詳細

変更前の挙動 (概念的なイメージ)

String#squish は概ね次の処理をしています:

  • 先頭と末尾の空白を削除(strip! 相当)
  • 残りの文字列中の「連続する空白」を 1 文字の空白 " " に置き換え

この「連続する空白」の検出に、従来は次のような単純な正規表現を使っていました:

ruby
gsub!(/[[:space:]]+/, " ")

[[:space:]] は Ruby の POSIX 文字クラスで、「空白文字全般(スペース、タブ、改行など)」を意味します。
+ が付いているため、「1 文字以上」の連続する空白をすべて " " に変換していました。

問題点

  • 通常のテキストでは「単一の半角スペース " "」が非常に頻繁に出現する
  • しかし String#squish 的には「連続する空白」や「改行・タブなどをスペース化」できればよく、すでに単一の " " である箇所は変換する必要がない
  • それにもかかわらず、全ての " " に対して正規表現マッチが走り、gsub! の処理コストが増大していた

変更後の正規表現

PR では、以下のようなアイデアで正規表現を組み立てています:

「2 文字以上の空白」あるいは「スペース以外の空白(タブ・改行など)」にだけマッチさせる

説明文中のベンチマーク例では、opt 実装用に次の正規表現を使っています:

ruby
gsub!(/([[:space:]]{2,}|[[[:space:]]&&[^ ]])/, " ")

これを分解すると:

  • [[:space:]]{2,}
    → 空白文字(スペース、タブ、改行など)が 2 文字以上連続している部分
    → 連続スペースや「スペース+改行」のような固まりにマッチ

  • [[[:space:]]&&[^ ]]
    → 「空白である」かつ「スペースではない」文字
    → タブ(\t) や改行(\n)、その他の空白文字にマッチ

  • (...|...)
    → 上記どちらかに当てはまる部分だけを " " に変換

これにより:

  • 既に「単一の " "」になっている場所は、そのまま残す(マッチさせない)
  • 「連続した空白」や「タブ・改行など」は従来通り " " に正規化される

正規表現自体は複雑になり、個々のマッチ処理はやや重くなり得ますが、「マッチするパターン自体を大幅に絞る」ことで、gsub! 全体としては速くなる、という発想です。

strip! についての補足

PR の本文には一度:

先に strip! を呼び出して、gsub で先頭・末尾の空白をマッチさせないようにして高速化する

という変更案がありましたが、

  • strip は「ASCII スペースだけ」ではなく Ruby が定義する空白全般をきちんと扱う必要がある
  • String#squish と同等の [[:space:]] 的な意味での「前後空白」を安全に strip するのは簡単ではない

といった理由から、この部分は取り下げられています。
そのため、最終的なマージ済みコードでは「正規表現のチューニング」に主眼が置かれており、strip! の呼び出し順や有無は従来の設計から大きくは変えていません。

ベンチマーク結果

PR に添付されている計測では:

  • Ruby: 4.0.0 + YJIT + PRISM
  • テスト文字列: (" sdsd dfdsf dfdsf\n dfdsf dfdsf" * 400).freeze

結果:

  • 旧実装: 約 5,011 i/s(1 回あたり ~200 μs)
  • 新実装: 約 9,972 i/s(1 回あたり ~100 μs)

つまり、テスト条件下では 約 2 倍高速化 しています。
著者コメントでは「テキスト内容によって増減はあるが、遅くなるケースは想像しづらい」と述べられています。


  1. 影響範囲・注意点
  • String#squish の外部仕様は基本的に変わらない想定

    • 「前後の空白を削る」「内部の空白や改行・タブを 1 つのスペースにまとめる」という仕様は維持されています。
  • ただし、正規表現の挙動が微妙に変わるため、以下のようなケースで差異が出る可能性はあります:

    • 非 ASCII の空白文字(全角スペース、Unicode の様々な空白カテゴリ文字)を非常に厳密にテストしているコード
    • ActiveSupport ではなく「Rails の squish の挙動そのもの」を仕様として利用しているようなユニットテスト
  • パフォーマンス面:

    • 長いテキスト(多くの半角スペースを含む文章、HTML など)に対して squish を大量に呼ぶアプリケーションでは、目に見えて CPU 使用量が下がる可能性があります。
    • 一方で、ほぼ空白がない文字列や極端に特殊な空白構成の文字列でだけ処理している場合には、体感できる差が出ないケースもあります。
  • 互換性面:

    • String#squish の結果文字列をさらに gsub(/\s+/, ...) などで加工しているコードがある場合、新しい正規表現が原因で「中間表現」が変わる可能性はゼロではありませんが、実務上そこまで依存したコードは稀と思われます。

  1. 参考情報 (あれば)
  • 該当 PR: https://github.com/rails/rails/pull/56626
  • 実際に効果を見るには、アプリケーション側で String#squish を多用している箇所(ログ整形、HTML テンプレートのミニファイ、テキスト正規化処理など)に対してベンチマークを取ると、どの程度効くかを確認できます。

#56622 Fix ActionView::TestCase expose variables assigned in setup

マージ日: 2026/1/16 | 作成者: @byroot

  1. 概要 (1-2文で)
    ActionView::TestCase で setup 内などで代入したインスタンス変数が、ビューで参照できなくなっていた不具合を修正する PR です。テストケース内でのインスタンス変数の扱いを元の(期待される)挙動に戻し、ビューに正しく「露出」されるようにしています。

  1. 変更内容の詳細

※ 実際の差分は actionview/lib/action_view/test_case.rb の 2 行追加 / 5 行削除のみで、かなりピンポイントな修正です。PR/Issue の文脈から読み取れる挙動を中心に説明します。

背景

  • Rails 7.2 の ActionView::TestCase 周辺で行われたリファクタリング(Ref: #56476)により、
    • テストクラス内の setup やテストメソッドで定義した @foo などのインスタンス変数が、
    • ビュー描画時に使われる view オブジェクト側にコピーされない(=ビューで参照できない)
      という回 regress(後退バグ)が発生していました。
  • これによって、従来動いていた以下のようなテストが失敗するようになっていました:
ruby
class ArticlesViewTest < ActionView::TestCase
  setup do
    @article = Article.new(title: "Hello")
  end

  test "renders article title" do
    render template: "articles/show"
    assert_select "h1", "Hello"
  end
end

ビュー側 (articles/show.html.erb) で @article.title を参照していると、@articlenil になったり NameError になったりする状況です。

修正の狙い

  • ActionView::TestCase が本来持つべき以下の性質を復元しています:
    • テストインスタンス (self) に定義されたインスタンス変数を、ビューにレンダリングする際に view コンテキストへ引き継ぐ(expose)
    • 特に setup ブロックやテストメソッドで代入した変数が対象

実際の変更点(概念的な説明)

ActionView::TestCase で、インスタンス変数をビューへセットアップする処理が簡略化/削除されていたものを、再度有効にした形です。概念的には以下のような処理が行われます:

ruby
# 擬似コードイメージ
def assign_variables_to_view
  instance_variables.each do |name|
    next if name.to_s.start_with?("@_") # 内部用を除外
    view.instance_variable_set(name, instance_variable_get(name))
  end
end

今回の PR では、このロジックに関わるコードが 1 ファイルで微修正され、setup 内で設定したインスタンス変数も正しくビューに流れるように戻されています。


  1. 影響範囲・注意点
  • 影響を受ける対象:
    • ActionView::TestCase を使ったビューテスト
    • 特に setup ブロック、もしくはテストメソッド内で @foo のようなインスタンス変数をセットし、それをテンプレート内で使っているケース
  • プロジェクトへの実質的な影響:
    • 以前の Rails バージョンで通っていたビューテストが、最新の 7.2 系などで突然落ちていた場合、この修正で元通り通るようになる可能性が高いです。
    • 逆に、「インスタンス変数がビューに渡らない前提」でワークアラウンドを書いていた場合、その前提は再度無効になります(ただしそうしたコードはかなりレアケースと考えられます)。
  • マイグレーション上の注意:
    • ActionView::TestCase 周りで最近テストが失敗していた場合、Rails をこの修正が入ったバージョンに上げたうえで、ワークアラウンド(例: ローカル変数経由に書き換えた等)が不要かどうかを見直してください。

  1. 参考情報 (あれば)

#56620 Pin connection_pool to version 2 on 7-2-stable

マージ日: 2026/1/16 | 作成者: @yahonda

  1. 概要 (1-2文で)
    Rails 7.2 の安定ブランチ(7-2-stable)で CI が落ちないようにするため、connection_pool のバージョンを 2 系に固定(pin)した PR です。Rails 7.2 は Ruby 3.1 をサポートしている一方で、connection_pool 3 系が Ruby 3.2 以上必須になったことへの対応です。

  1. 変更内容の詳細

何をしているか

変更ファイルは 1 つだけです。

  • activesupport/activesupport.gemspec
    • 依存関係として指定している connection_pool のバージョンを「2 系に固定」するよう変更

※ 実際の差分イメージ(概念的な例):

ruby
# 変更前(例)
spec.add_dependency "connection_pool"

# 変更後(例)
spec.add_dependency "connection_pool", "~> 2.0"

※ PR 本文には行数 (+1/-1) だけが示されており、正確な演算子(~>, =, >= など)は明記されていませんが、「version 2 に pin」とあるので 2 系のみに制限する指定がなされています。

背景・理由

  • connection_pool 3.x 系の gemspec 側で「Ruby 3.2 以上」を必須とするようになった:
  • 一方、Rails 7.2 は Ruby 3.1 も公式サポート対象。
  • そのため 7-2-stable ブランチでテストを回すと、環境によっては connection_pool 3.x が入ろうとして Ruby バージョン要件に引っかかり CI が落ちる。
  • CI を安定させるために「7-2-stable では connection_pool 2 系を使う」と明示する必要があった、というのがこの PR のモチベーションです。

リリース方針との関係

  • Rails 7.2 はすでに「Security Release only」フェーズに入っており、通常のリリースは行われません。
  • 今後の 7.2 のセキュリティリリースは v7.2.3 をベースに行われ、7-2-stable ブランチから直接リリースされるわけではないため、この変更自体は「CI を緑に保つためのメンテ用変更」であり、利用者向けには出回らない想定です。

  1. 影響範囲・注意点
  • 影響範囲

    • 対象は「Rails 7.2 の 7-2-stable ブランチ上での開発・CI 実行環境」に限定されます。
    • 実際の公式リリース gem にはこの変更が乗らない前提であるため、通常の Rails 7.2 利用者には影響はありません。
    • 7-2-stable を追いかけている人(独自ビルドや独自フォーク環境)は connection_pool が 2 系に固定される点に注意が必要です。
  • 技術的な注意点

    • Ruby 3.1 環境で 7-2-stable を動かす場合に bundle update などで connection_pool 3.x が入って CI/テストがこける問題は、今回の pin によって回避されます。
    • 逆に、Ruby 3.2 以上で connection_pool 3.x の新機能や変更を試したい場合でも、7-2-stable では 2 系に縛られることになります。
    • この PR ではテスト追加や CHANGELOG 更新は行われておらず、あくまで「依存バージョン指定の調整」のみです。

  1. 参考情報 (あれば)

#56351 [Docs] Document swappable migration backend behaviour

マージ日: 2026/1/14 | 作成者: @adrianna-chang-shopify

  1. 概要 (1-2文で)
    Railsの「Swappable Migration Strategies(差し替え可能なマイグレーション実行バックエンド)」機能について、ガイドとAPIドキュメントを充実させたPRです。実装自体の挙動変更はほぼなく、ExecutionStrategyDefaultStrategyクラスの正式な説明と、使い方・カスタマイズ方法が明文化されています。

  1. 変更内容の詳細

2-1. Active Record Migrations ガイドの拡張

guides/source/active_record_migrations.md に「Swappable Migration Strategies」に関する新セクションが追加されています。主な内容は:

  • 目的

    • マイグレーションの「実行方法」をアプリ側で差し替え可能にする仕組みを公式に説明
    • 例:
      • 本番では専用サービス経由でマイグレーションを非同期実行
      • シャーディング環境で、マイグレーションを複数DBに分配
      • 特定アダプタ(PostgreSQL / MySQLなど)ごとに異なる戦略を利用
  • 基本コンセプト

    • これまで rails db:migrate は内部的に「マイグレーションをどう実行するか」を固定実装で持っていた
    • Swappable Strategy では、その部分を ExecutionStrategy というオブジェクトに切り出し、アプリケーション側が差し替えられる
  • 設定方法の説明(内容イメージ)

    • グローバルな設定例(全アダプタ共通で同じ戦略を使う):

      ruby
      # config/application.rb
      module MyApp
        class Application < Rails::Application
          config.active_record.migration_strategy = MyCustomMigrationStrategy
        end
      end
    • アダプタごとに戦略を変える設定例:

      ruby
      # config/application.rb
      module MyApp
        class Application < Rails::Application
          config.active_record.migration_strategies = {
            "postgresql" => PostgresMigrationStrategy,
            "mysql2"     => MySQLMigrationStrategy,
          }
        end
      end
    • 上記のような「per-adapter strategies」対応は、以前の PR (#56204) で追加された機能であり、その使い方もガイドに明記

  • カスタム戦略の実装例(概要)

    • ActiveRecord::Migration::ExecutionStrategy を継承し、特定のメソッドを実装することで、独自のマイグレーション実行フローを定義できる、という流れが文章とサンプルコードで示されている想定です。
    • 例として、Shopify のような「本番ではキューに投入して別プロセスが実行する」戦略を実装するパターンなどが概念的に解説されている。

2-2. ActiveRecord::Migration::ExecutionStrategy のドキュメント整備

activerecord/lib/active_record/migration/execution_strategy.rb にコメントと API ドキュメントが追加されています。

  • 役割

    • マイグレーションの実行を抽象化するためのベースクラス/インターフェイス的存在であることを明示
    • 典型的には、以下のような責務を担うクラスであると説明されている:
      • 実際に up / down をどのように実行するか
      • トランザクションの扱い
      • ロギング・エラー処理
      • 複数DBや外部サービスへの委譲など
  • カスタム実装のポイント

    • このクラスを継承して、自分の戦略クラスを実装するのが推奨パターンであること
    • (コメントから読み取れる範囲で)オーバーライドすべきメソッドや、コールされるライフサイクルの流れが明文化されている

2-3. ActiveRecord::Migration::DefaultStrategy のドキュメント整備

activerecord/lib/active_record/migration/default_strategy.rb にも詳細なコメント・API ドキュメントが追加されています。

  • 役割

    • 既存の Rails が使っていた「標準的なマイグレーション実行方法」を提供するクラスであり、ExecutionStrategy のデフォルト実装であることを明記
    • 何も設定しなければこの戦略が使われるため、後方互換性の基準にもなる
  • 挙動の説明

    • 通常の rails db:migrate が行っていること(schema_migrations の更新、実行履歴の記録、トランザクションの扱い など)を包括した戦略であること
    • 他のカスタム戦略を実装する際、このクラスを参考実装として読むことを推奨するような位置づけで説明されている

  1. 影響範囲・注意点
  • 機能面の変更はほぼなし

    • 既存の挙動を変えるコード変更ではなく、主にドキュメント・コメントの追加が中心
    • デフォルト戦略 (DefaultStrategy) の挙動は変わらず、既存アプリはそのまま動作
  • 開発者にとっての実務的な影響

    • これまでコードリーディングや外部ブログに頼っていた、Swappable Migration Strategies の使い方が公式ガイドで説明されるようになった
    • 本番環境や大規模環境(シャーディング、多数DBなど)で「マイグレーションの実行方法をカスタマイズしたい」場合の入口が明確になった
    • 今後この API を前提にしたカスタマイズや gem が出てきても、公式にサポートされた拡張ポイントとして扱いやすくなる
  • 注意点

    • 実際にカスタム戦略を書く場合は、マイグレーションの整合性・エラー時ロールバック・再実行可能性など、DefaultStrategy が面倒を見ていることを自前で担保する必要がある
    • per-adapter 戦略を使う場合、アダプタ名のキー("postgresql", "mysql2" など)は接続設定で利用しているアダプタ名に正しく合わせる必要がある

  1. 参考情報 (あれば)

#56613 Remove unused connection arg

マージ日: 2026/1/14 | 作成者: @skipkayhil

  1. 概要 (1-2文で)
    このPRは、Active Record の属性タイプ関連コードから「使われていない connection 引数」を削除し、メソッドシグネチャを整理したものです。挙動自体は変えずに、以前の変更 (#56484) の取りこぼしをクリーンアップしています。

  1. 変更内容の詳細

※PR本文と差分情報から推測される内容を整理しています(実際のコードはURL先コミットで確認するのが確実です)。

  • 対象: Active Record の属性定義まわり

    • activerecord/lib/active_record/attributes.rb
    • activerecord/lib/active_record/model_schema.rb
  • 背景:

    • 以前のコミット で、属性タイプを扱うコードが DB コネクションに依存しないようリファクタリングされました。
    • その際、「メソッドの引数として connection を受け取るが、実際には中で一切使っていない」という状態のメソッドが残っていました。
    • さらに、そのメソッドは「connectionnil を渡して呼ばれる」想定のままでしたが、実際には値を参照していませんでした。
  • このPRでの具体的変更:

    • 上記メソッド(属性タイプを初期化/決定するような箇所と考えられます)から connection 引数を削除。

    • それに伴い、そのメソッドを呼び出している側(model_schema.rb 側)も connection 引数を渡さないように修正。

    • 実質的には以下のような変更イメージです(擬似コード):

      ruby
      # 変更前(イメージ)
      def some_attribute_method(name, type, connection: nil)
        # connection は使われていない
        build_type_metadata(name, type)
      end
      ruby
      # 変更後(イメージ)
      def some_attribute_method(name, type)
        build_type_metadata(name, type)
      end
      ruby
      # 呼び出し側(イメージ)
      # 変更前
      some_attribute_method(attr_name, attr_type, connection: nil)
      
      # 変更後
      some_attribute_method(attr_name, attr_type)
  • 差分規模:

    • 追加 3 行 / 削除 3 行と非常に小さい変更で、リファクタリング的性質が強いです。

  1. 影響範囲・注意点
  • Rails 本体の挙動:

    • connection 引数は元々使われていなかったため、Rails の実行時挙動・クエリ発行・型変換ロジックなどに機能的な変更はありません。
    • 既存のテストが通る前提でマージされているため、フレームワーク利用者への実質的な挙動変化はないと考えてよいです。
  • プラグイン/アプリ側の影響:

    • 以下のようなケースでは影響が出る可能性があります:
      • Rails 内部の ActiveRecord::AttributesModelSchema の「内部メソッド」を直接呼び出しており、そのメソッドに connection 引数を渡していた場合。
      • Active Record の内部 API を monkey patch しており、メソッドシグネチャ (def foo(..., connection: nil)) に依存している場合。
    • ただし、通常のアプリケーションコードはこうした内部メソッドに直接触れないため、大半のアプリには影響ありません。
  • マイグレーションや接続管理への影響:

    • connection を使わない方向へのリファクタリングの一環ですが、マイグレーションの書き方や establish_connection などへの影響はありません。

  1. 参考情報 (あれば)
  • 関連 Issue/PR:
    • Ref: #56484 — 属性タイプコードから接続依存を取り除いた前回の変更。
  • コミット:
  • 位置付け:
    • Rails 7.x/8.x 系の Active Record 内部 API のクリーンアップの一部であり、将来の内部構造変更や抽象化(例: 接続プーリング・マルチ DB・DB 以外のバックエンドなど)をシンプルにする土台作りと考えられます。

#56609 Add input validation to Array#in_groups

マージ日: 2026/1/14 | 作成者: @Saidbek

  1. 概要 (1–2文で)
    Array#in_groups に、Array#in_groups_of と同等の入力バリデーションが追加され、無効な引数を渡した際に、これまでの「よく分からないエラー」ではなく明確な例外が発生するようになりました。これにより、誤った引数指定時のデバッグが容易になります。

  1. 変更内容の詳細

背景

Array#in_groups は配列を指定したグループ数に分割する ActiveSupport の拡張メソッドです。
一方で、似たメソッドである Array#in_groups_of には引数に対するバリデーションがすでに入っていましたが、in_groups 側にはそれがなく、次のようなケースで内部エラー的な挙動になっていました。

  • グループ数に 0 や負数を渡す
  • 整数でない値(小数・文字列など)を渡す

この PR は、in_groups にも同様のバリデーションを入れることで、この不整合を解消しています。

実際の変更点

該当ファイル:

  • activesupport/lib/active_support/core_ext/array/grouping.rb
  • activesupport/test/core_ext/array/grouping_test.rb

主な内容:

  1. Array#in_groups に引数チェックを追加

    概ね以下のようなチェックが冒頭で行われるようになったと考えられます(実際の実装イメージ):

    ruby
    def in_groups(number, fill_with = nil, &block)
      number = number.to_i
      raise ArgumentError, "Group number must be positive" if number <= 0
    
      # 既存のグルーピング処理がこの後に続く
    end

    これにより、これまで例えば:

    ruby
    [1, 2, 3].in_groups(0)

    のようなコードを書いたときに、内部で ZeroDivisionError や、もっと分かりづらいエラーになっていたのが、意図した ArgumentError(かつ分かりやすいメッセージ)として扱われます。

  2. テストの追加

    activesupport/test/core_ext/array/grouping_test.rb に、以下のようなケースに対応するテストが追加されています:

    • グループ数に 0 を渡すと ArgumentError が発生する
    • グループ数に負数を渡すと ArgumentError が発生する
    • グループ数に数値以外を渡した場合の挙動(to_i される or エラーになる)を確認

    これにより、今後このバリデーションが壊れないように担保されています。


  1. 影響範囲・注意点
  • 破壊的変更の可能性
    これまで「たまたま動いていた」コードが、今回の変更で ArgumentError を投げるようになる可能性があります。
    例:

    ruby
    [1, 2, 3].in_groups(0)   # 以前: 内部エラーや想定外の挙動
                             # 今回以降: ArgumentError
  • in_groups と in_groups_of の挙動が揃う
    もともと in_groups_of では不正なサイズ指定に対してきちんとエラーが出ていたため、両者のインタフェースが一貫しました。
    つまり「グルーピングメソッドには妥当な正の整数を渡す」という前提がより明確になります。

  • マイグレーションやバッチ処理での利用時に要確認

    • 動的に算出したグループ数を in_groups に渡している場合、その計算結果が 0 や負数になり得るなら、この変更で例外が出るようになります。
    • そのようなコードがある場合は、事前に
      ruby
      groups = [計算ロジック]
      if groups <= 0
        # groups が 0 や負数のときの代替挙動を定義
      else
        array.in_groups(groups)
      end
      のように防御的なコードにしておく必要があります。

  1. 参考情報 (あれば)
  • 対応 Issue: https://github.com/rails/rails/issues/56608
  • 関連メソッド: Array#in_groups_of (同じファイル grouping.rb 内で定義されており、こちらを参考にした入力バリデーションが追加されたと考えられます)
  • Array#in_groups は ActiveSupport のコア拡張で、標準の Ruby Array には存在しないため、Rails/ActiveSupport を利用しない純 Ruby 環境には影響しません。

#56601 Allow retry_on wait procs to accept error as a second argument

マージ日: 2026/1/14 | 作成者: @jpcamara

  1. 概要 (1-2文で)
    Active Job の retry_on オプションに渡す wait Proc が、これまでの「実行回数」だけでなく「発生したエラーオブジェクト」も受け取れるようになりました。これにより、エラー内容に応じた柔軟なリトライ待ち時間の制御が可能になります(既存コードとの互換性は維持)。

  1. 変更内容の詳細

何ができるようになったか

retry_onwait: に Proc(もしくは lambda)を渡す際、その引数として以下を指定できるようになりました:

  • 従来: ->(executions) { ... }
  • 新規: ->(executions, error) { ... }

新しい形では、リトライ対象の例外オブジェクトを第2引数として受け取り、その情報を元に待ち時間を動的に決定できます。

サンプルコード

ruby
class RemoteServiceJob < ActiveJob::Base
  retry_on CustomError, wait: ->(executions, error) {
    # 例: エラーが retry_after を持っていればそれを優先し、
    # なければ「実行回数 x 2秒」で待つ
    error.retry_after || executions * 2
  }

  def perform
    # リモートAPI呼び出しなど
  end
end

例えば、HTTP クライアントのエラークラスに retry_after(HTTP の Retry-After ヘッダなどをパースした値)を持たせておけば、サーバー側の指示に従った待ち時間でリトライできるようになります。

実装上のポイント

  • 変更箇所は ActiveJob::Exceptions#call_retry_delay_algorithm
  • wait に渡された Proc の arity(引数の数)を見て、呼び出し方法を変えています:
    • arity 0 or 1: proc.call(executions) のみ(従来通り)
    • arity 2 以上: proc.call(executions, error)
  • これにより、既存の wait: ->(executions) { ... }wait: -> { ... } は一切挙動が変わりません。

テスト面では:

  • 既存テストは全て通過
  • 「2引数の wait Proc がエラーオブジェクトを受け取り、期待通り動作すること」を確認する新しいテストが追加されています。

  1. 影響範囲・注意点

影響範囲

  • 対象: Active Job の retry_onwait: Proc 付きで利用しているジョブ
  • 既存コード:
    • wait の arity が 0 または 1 の場合、挙動は一切変わりません。
    • arity に応じて分岐しているコードがなければ、後方互換性が保たれます。
  • 新規コード:
    • 2引数以上の Proc を指定した場合のみ、error が第2引数として渡されるようになります。

注意点・設計時の考慮

  • エラー型に依存したロジック
    wait 内で error のクラスやメソッドに依存する場合、そのエラーが本当に retry_on で指定している型・サブクラスであることを前提にしてください。

    • 例: error.retry_after を呼ぶ場合、そのメソッドが必ず定義されているエラー型だけに retry_on を適用するようにする。
  • arity ベースの分岐
    フレームワーク側は arity を見ているため、例えば以下のような形式でも、Ruby の arity ルールに従って扱われます:

    • ->(*) { ... } など可変長引数を使うと arity の値が変わる点に注意(通常の2引数 lambda を使うのが安全)。
  • 待ち時間は数値で返す前提
    従来通り、wait Proc は「秒数などの待ち時間(数値)」を返すことが前提です。例外を投げるとその時点で失敗扱いになるので、エラーを受け取ることでロジックが複雑になる場合は、例外ハンドリングを含めて設計してください。


  1. 参考情報 (あれば)
  • 変更ファイルの主なポイント:
    • activejob/lib/active_job/exceptions.rb
      call_retry_delay_algorithmwait Proc の arity に応じた呼び分けを実装。
    • activejob/test/cases/exceptions_test.rb / activejob/test/jobs/retry_job.rb
      2引数 Proc で error を受け取るケースのテストが追加。
    • activejob/CHANGELOG.md
      機能追加として本変更が記載。

この変更は、APIクライアントジョブや外部サービスとの連携ジョブにおいて、レートリミットや一時的な障害に対して「サーバー側が提示する待ち時間」をきちんと反映させたい場合に特に有用です。


#56587 Deprecate Resque Active Job adapter

マージ日: 2026/1/14 | 作成者: @morgoth

  1. 概要 (1-2文で)
    Rails に同梱されていた Active Job の Resque アダプタが「deprecated(非推奨)」になり、今後は resque gem 側に含まれるアダプタを使うよう誘導する変更です。機能自体はすぐになくなるわけではありませんが、将来的な削除に向けた移行案内の位置づけです。

  1. 変更内容の詳細

2-1. CHANGELOG の更新

activejob/CHANGELOG.md に以下の趣旨が追記されています(要約):

  • Resque の Active Job アダプタ(ActiveJob::QueueAdapters::ResqueAdapter)を非推奨とした。
  • Resque 用の Active Job アダプタは resque gem v3.0.0 以降に含まれるため、そちらを利用するよう促す内容。

これにより、Rails のリリースノート/CHANGELOG を読めば「Resque アダプタは Rails 本体からは廃止方向で、今後は resque gem 側を使う」という方針が明確になります。


2-2. Resque アダプタ本体の変更

activejob/lib/active_job/queue_adapters/resque_adapter.rb に非推奨のマークとメッセージが追加されています。

実装のイメージは次のような内容です(実際のコードを分かりやすくした疑似コード):

ruby
# activejob/lib/active_job/queue_adapters/resque_adapter.rb

module ActiveJob
  module QueueAdapters
    class ResqueAdapter
      # 新しく追加された非推奨宣言
      ActiveSupport::Deprecation.warn(
        "ActiveJob::QueueAdapters::ResqueAdapter は非推奨です。" \
        "今後は resque gem に含まれている Active Job アダプタを使用してください。"
      )

      # 既存の実装はそのまま(enqueue, enqueue_at など)
      def enqueue(job)
        # ...
      end

      def enqueue_at(job, timestamp)
        # ...
      end
    end
  end
end

ポイント:

  • ResqueAdapter をロードしたタイミング、または利用したタイミングで deprecation warning が出るようになっている。
  • 実際の enqueue 処理などのロジック自体は削除されておらず、あくまで「非推奨になりました」と知らせるだけの変更。

(実際のコード上は ActiveSupport::Deprecation.deprecate_constantActiveSupport::Deprecation.warn のような仕組みが用いられているはずで、そのいずれか/組み合わせで非推奨を表現しています。)


2-3. テストの更新

activejob/test/cases/adapter_test.rb に、Resque アダプタの非推奨を確認するテストが追加されています。

おおまかな内容は以下のようなものです:

ruby
def test_resque_adapter_is_deprecated
  assert_deprecated do
    ActiveJob::Base.queue_adapter = :resque
  end
end

このようなテストにより、「Resque アダプタを使おうとすると deprecation warning が出る」という挙動が自動テストで担保されます。


  1. 影響範囲・注意点

3-1. 既存の Resque 利用プロジェクトへの影響

  • すでに queue_adapter = :resque を使っている Rails アプリは、Rails をこの変更を含むバージョンに上げると deprecation warning がコンソール・ログに出る ようになります。
    • 機能は即座に壊れませんが、「将来 Rails 本体からこのアダプタは削除される予定」というサインです。

3-2. 推奨される移行方針

今後は resque gem v3.0.0 以降に含まれる Active Job アダプタ を利用する必要があります。基本的な移行の流れは次のとおりです:

  1. Gemfile を確認・更新:

    ruby
    gem "resque", "~> 3.0"
  2. 既に queue_adapter = :resque を設定している場合でも、今後は resque gem 側のアダプタが読み込まれるように設定や require 周りを確認する必要があります。
    (resque 3.0.0 以降では、require "resque/active_job" のような形でアダプタを読み込む設計になっている可能性があります。実際の使い方は resque の README / リリースノートを確認してください。)

  3. Rails 本体側の Resque アダプタに依存しているコード(クラス名を直指定している、など)がある場合は、resque gem 側のアダプタ名 / モジュール構成に揃えて修正してください。

3-3. 将来的な削除リスク

  • 今は「deprecate(非推奨)」の段階であり、まだ動作はしますが、今後の Rails メジャーバージョンアップで ResqueAdapter 自体が削除 される可能性が高いです。
  • メンテナンス性の観点からも、早めに resque gem 側に移行しておくのが安全です。

  1. 参考情報 (あれば)

#56607 Fix RACK_ENV environment leak in ActionCable ClientTest

マージ日: 2026/1/14 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Action Cable の ClientTest 実行時に、Puma が設定した RACK_ENV 環境変数がテスト後も残り続けてしまう問題を修正した PRです。これにより、LeakChecker による「Environment leak detected: Added variables: RACK_ENV」というエラーが発生しなくなります。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル: actioncable/test/client_test.rb
  • 追加行数: 4 行(削除なし)
  • 目的: テスト中に Puma が設定した RACK_ENV をテスト終了後にクリーンアップし、テスト環境での環境変数リークを防ぐ。

具体的には:

  • ClientTest で WebSocket サーバとして Puma を起動している(または利用している)際、Puma が ENV["RACK_ENV"] をセットする。
  • Rails のテストスイートには、テスト実行前後で環境変数の差分を検査する LeakChecker があり、テスト前に存在しなかった環境変数がテスト後に残っていると「Environment leak」として失敗扱いされる。
  • 今回の修正では、ClientTest のセットアップ/ティアダウン(setup / teardown もしくは ensure ブロック)に、テストの前後で ENV["RACK_ENV"] を保存・復元または削除するロジックが追加されています。

イメージとしては、以下のようなパターンが追加されていると考えられます(実際のコードは多少異なる可能性がありますが、やっていることはこれと同等です):

ruby
class ClientTest < ActiveSupport::TestCase
  def setup
    super
    @original_rack_env = ENV["RACK_ENV"]
  end

  def teardown
    super
    if @original_rack_env.nil?
      ENV.delete("RACK_ENV")
    else
      ENV["RACK_ENV"] = @original_rack_env
    end
  end
end

もしくは、テストケース全体を ensure で囲んで、テスト開始前の環境を必ず復元するような形です。


  1. 影響範囲・注意点
  • 影響範囲

    • Rails コアの Action Cable クライアント向けテスト (ActionCable::ClientTest) のみ。
    • プロダクションコード(Action Cable / Puma 本体の挙動)には影響しません。
    • テストスイートの安定性向上 (特に LeakChecker を有効化した環境) に寄与します。
  • 開発者視点でのポイント

    • Rails 本体のテストをローカルで流していて「Environment leak detected: Added variables: RACK_ENV」で落ちていた場合、この PR がマージされたバージョン以降では解消されます。
    • 自分のアプリケーションや gem のテストで Puma を起動しており、同様に LeakChecker や環境リーク検知をしている場合も、同じパターンで「テスト前の ENV を保存してテスト後に復元する」実装を適用するのが望ましいです。
    • RACK_ENV に依存する処理をテストで書く場合、他テストとの間で ENV["RACK_ENV"] の状態が汚染されないよう、この PR と同様のクリーンアップを行うことがベストプラクティスになります。
  • 注意点

    • RACK_ENV をテストコード側で意図的に変更している場合でも、テスト終了後には元の状態に戻される前提となるため、「テスト間で RACK_ENV を持ち回る」ような設計は避ける必要があります(そもそもアンチパターンですが)。
    • もし独自のテストヘルパー内で Puma を起動している場合、今回の修正のように「Puma が暗黙にセットする環境変数」をケアしているかどうかを確認した方が安全です。

  1. 参考情報 (あれば)
  • 対応 Issue: https://github.com/rails/rails/issues/56606
    • 内容: Rails テストで Puma を使った Action Cable クライアントテスト実行後に RACK_ENV が残り、LeakChecker が「Environment leak detected: Added variables: RACK_ENV」と報告する問題。
  • 関連知識:
    • Puma は Rack サーバであり、起動時に RACK_ENV を設定する挙動がある。
    • Rails 本体のテストでは ActiveSupport::Testing::Isolation や独自の LeakChecker によって、グローバル状態(環境変数・定数・ロード済みファイルなど)のリークがないか厳密にチェックしている。
    • そのため、サーバ起動や外部ライブラリ利用で暗黙に変更されるグローバル状態(今回の RACK_ENV のようなもの)は明示的に復元・クリーンアップする必要がある。

#56585 Improve the ScreenshotHelper docs

マージ日: 2026/1/13 | 作成者: @codergeek121

  1. 概要 (1-2文で)
    ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper のドキュメントが改善され、HTML スクリーンショットを有効化するための環境変数 RAILS_SYSTEM_TESTING_SCREENSHOT_HTML の具体的な設定値(1)が明示されました。実装自体の挙動変更はなく、ドキュメントの明確化のみです。

  1. 変更内容の詳細

対象:
actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb

このファイル内に書かれている ScreenshotHelper のドキュメントコメントが 1 行だけ修正されています。

もともと:

  • RAILS_SYSTEM_TESTING_SCREENSHOT_HTML をセットすれば HTML スクリーンショットが有効になる」程度の説明で、「何をセットするのか(値)」が不明確だった。

今回の修正で:

  • RAILS_SYSTEM_TESTING_SCREENSHOT_HTML=1 を環境変数として設定すると、HTML スクリーンショットが有効になる」という形で、「値として 1 をセットする必要がある」ことが明示された。

そのため、利用者は以下のように設定すればよいことがドキュメントから直接わかるようになります。

bash
# 例: HTML スクリーンショットを有効にして system test を実行
RAILS_SYSTEM_TESTING_SCREENSHOT_HTML=1 bin/rails test:system

PR 説明文にもあるとおり、現在のコードは「値が 1 のときのみ有効」という条件になっており、0true など他の値では有効にならない実装です。その点がドキュメント上で暗黙的だったのを、明示した形です。


  1. 影響範囲・注意点
  • 実装の挙動は変わっていない

    • すでに RAILS_SYSTEM_TESTING_SCREENSHOT_HTML=1 を使っていたプロジェクトには一切影響ありません。
    • 変更はコメント(ドキュメント)のみです。
  • 環境変数の値に関する注意

    • HTML スクリーンショットを有効にするには、RAILS_SYSTEM_TESTING_SCREENSHOT_HTML1 に設定する必要がある ことが明文化されました。
    • RAILS_SYSTEM_TESTING_SCREENSHOT_HTML=trueRAILS_SYSTEM_TESTING_SCREENSHOT_HTML=yes など、真偽値っぽい別の文字列では有効にならない点に注意してください。
  • 代替案としての挙動変更案について

    • PR 説明にある「ENV.key?("RAILS_SYSTEM_TESTING_SCREENSHOT_HTML") を使う」という案は「存在していれば有効」とする挙動変更であり、互換性に影響し得るため今回は採用されていません。
    • 将来的にこのような仕様変更を行う場合は、RAILS_SYSTEM_TESTING_SCREENSHOT_HTML にどんな値を入れても(空でも)存在すれば有効になるような形になる可能性がありますが、本 PR はあくまで現状仕様の明文化に留まります。

  1. 参考情報 (あれば)
  • 対象モジュール:
    ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper
    システムテスト失敗時にスクリーンショット(画像や HTML)を保存するためのヘルパーです。
  • 利用シーンの例:
    • system test が失敗したときにブラウザの状態を再現するため、HTML を保存してデバッグしたい場合に、RAILS_SYSTEM_TESTING_SCREENSHOT_HTML=1 を指定してテストを実行します。

#56590 [8-0-stable] Add missing with_info_handler removed in ec62932ee7

マージ日: 2026/1/13 | 作成者: @zzak

  1. 概要 (1-2文で)
    Rails 8.0-stable ブランチで、ActiveSupport::Testing::Parallelization::Worker から誤って削除されていた with_info_handler メソッドが復活・再定義されました。並列テスト実行時の情報ハンドラ設定まわりの挙動を、以前の想定どおりに戻す修正です。

  1. 変更内容の詳細

※PR本文から分かるのは「with_info_handler が削除されていたので戻した」という点と、対象ファイルのみです。Rails本体の構造と類似コードからの推測を含みます。

対象ファイル

  • activesupport/lib/active_support/testing/parallelization/worker.rb
    • 追加: 6行
    • 削除: 4行

ActiveSupport::Testing::Parallelization::Worker は、並列テスト実行時に個々のワーカープロセス側でテストを実行するロジックを持っています。その中で利用されていた with_info_handler というヘルパーメソッド(テストの情報出力用ハンドラを一時的に差し替えるラッパ)が、過去のコミット ec62932ee7 で削除されてしまっていたため、今回のPRで再度定義されました。

典型的には、以下のような形のメソッドが復活していると考えられます(あくまで構造イメージです):

ruby
# activesupport/lib/active_support/testing/parallelization/worker.rb

def with_info_handler(handler)
  previous_handler = @info_handler
  @info_handler = handler
  yield
ensure
  @info_handler = previous_handler
end

あるいは、Minitest / ActiveSupport::TestReporter などの「テスト情報の出力先(例: STDOUT, ファイル, ソケット)」をラップするような実装で、

ruby
def with_info_handler(io)
  old_handler = Minitest.reporter.io
  Minitest.reporter.io = io
  yield
ensure
  Minitest.reporter.io = old_handler
end

といった、「一時的に情報ハンドラを差し替えてブロックを実行し、必ず元に戻す」パターンである可能性が高いです。

with_info_handler が削除された結果、

  • そのメソッドを呼び出している箇所で NoMethodError が発生する
  • あるいは情報ハンドラの差し替えが行われず、標準出力やログの扱いが想定と異なる

といった問題が生じていたため、今回のPRは、それを以前と同じ振る舞いに戻すパッチとなっています。


  1. 影響範囲・注意点
  • 対象: Rails 8.0 系の並列テスト機能 (ActiveSupport::Testing::Parallelization) を利用している環境
  • 影響:
    • with_info_handler を内部で利用している箇所(テスト情報の出力・伝播を扱うコード)が、再び正常に動作するようになります。
    • もし worker.rb の挙動に依存して独自パッチや monkey patch を当てていた場合、今回のメソッド復活により衝突する可能性があります。
  • 注意点:
    • 8-0-stable を追従しているプロジェクトで、並列テスト実行時に「最近のコミット以降、テスト情報の出力がおかしい」「例外が出る」といった問題が出ていた場合、このPRで解消される可能性があります。
    • もし CI で Rails をブランチ指定して使っている場合、ec62932ee7 以降〜このPRマージ以前の範囲でのみ発生する一時的な不具合なので、Rails を更新するだけで直るケースが多いです。

  1. 参考情報 (あれば)

#56591 [8-1-stable] Add missing with_info_handler removed in 0f8014a0ff

マージ日: 2026/1/13 | 作成者: @zzak

  1. 概要 (1-2文で)
    Rails 8.1-stable ブランチの ActiveSupport テスト並列実行用ワーカーにおいて、以前のコミットで誤って削除されていた with_info_handler 呼び出しが復元されました。これにより、並列テスト実行時の情報ハンドラ(ログや進捗など)の扱いが再び正しく行われるようになります。

  1. 変更内容の詳細

※PR本文からは差分の全文は示されていませんが、タイトルと説明・行数から推測できる範囲で技術的に整理します。

背景

  • activesupport/lib/active_support/testing/parallelization/worker.rb は、テストを並列実行する際の「ワーカー」プロセス/スレッド側のロジックを担当するファイルです。
  • with_info_handler は、おそらく「テスト実行中の特定の情報(例:シグナルハンドラ、進捗情報、ログ出力のフックなど)を一時的に差し替えて実行する」ためのヘルパーメソッドです。
  • コミット 0f8014a0ff でこの with_info_handler 呼び出しが誤って削除され、その結果、並列テスト時に期待される情報ハンドリングが行われなくなっていました。
  • 今回の PR では、その削除による不具合を修正するため、with_info_handler を元に戻しています。

変更のイメージ

行数の増減 (+6/-4) から、おおよそ次のような修正が行われていると考えられます(擬似コード):

ruby
# 修正前 (0f8014a0ff による退行後のイメージ)
def run
  # 本来 with_info_handler で囲まれていた処理が
  # そのまま実行されていた状態
  perform_tests
end

# 修正後 (本PRでの復元イメージ)
def run
  with_info_handler do
    perform_tests
  end
end

もしくは、ブロックを受け取るメソッド呼び出しの中で with_info_handler を呼び出す形:

ruby
# 修正後の別パターンのイメージ
with_info_handler do
  worker_loop do |job|
    run_job(job)
  end
end

with_info_handler 自体は、例えばこんな実装になっている可能性があります(参考程度の擬似コード):

ruby
def with_info_handler
  previous_handler = Thread.current[:info_handler]
  Thread.current[:info_handler] = method(:handle_info)
  yield
ensure
  Thread.current[:info_handler] = previous_handler
end

重要なのは、「並列ワーカーがテストを実行する際に、本来の情報ハンドリングコンテキストを正しくセットする処理が復活した」という点です。


  1. 影響範囲・注意点

影響範囲

  • 対象: ActiveSupport の並列テスト機能 (ActiveSupport::Testing::Parallelization) を利用しているプロジェクト。
  • 特に、Rails 8.1 系で 0f8014a0ff 以降のコミットを取り込んでおり、かつ並列テスト実行時に情報ハンドリング周り(ログ、進捗、シグナルなど)で挙動の違和感を感じていた環境で影響があります。
  • 単一プロセステスト、もしくは並列化を使っていない場合には、ほぼ影響はありません。

想定される症状と改善

with_info_handler がない状態で起き得た問題:

  • 並列テスト実行中のログや進捗情報が期待通りに出ない。
  • 情報ハンドリング(シグナル、エラーレポーティングなど)が、親プロセス/メインスレッドとは異なる前提になってしまう。
  • シグナルや情報イベントを受け取った時の挙動が乱れる、あるいはまったく動かない。

今回の修正によって:

  • 元々想定されていた形で、ワーカーごとの情報ハンドラが有効になり、並列実行時の情報出力や制御が安定する。
  • 既存のテストが「以前の Rails バージョンでは通っていたのに、8.1 のある時点から並列実行時だけ不安定になった」場合、症状が解消される可能性があります。

注意点

  • 公開 API の追加・変更ではなく、内部実装の回復 (regression fix) に近いため、通常のアプリケーションコードの修正は不要なはずです。
  • 並列テスト周りをカスタマイズしている場合(独自に worker を拡張している、情報ハンドラにフックしているなど)は、この変更によって
    • with_info_handler が再び呼ばれる前提になる
    • 呼び出しのネスト構造やタイミングが変わる 可能性があるため、並列テストを一度フルで走らせて確認しておくと安心です。

  1. 参考情報 (あれば)

この PR は、Rails 8.1-stable ブランチに対するリグレッション修正の性格が強く、「失われていた安全装置 (with_info_handler) を元に戻した」ものと理解すると把握しやすいです。


#56568 [ci-skip] Fix broken code examples in AR finder methods doc

マージ日: 2026/1/13 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Active Record の finder メソッドのドキュメント内で使われていた、SQLのプレースホルダ構文が誤っていたコード例を修正したPRです。実装コード自体には手を入れておらず、ドキュメント用のサンプルコードのみが修正されています。

  1. 変更内容の詳細

変更対象:

  • activerecord/lib/active_record/relation/finder_methods.rb の中にある「ドキュメント用のコード例コメント」のプレースホルダ構文

元のコード例は「実際のRails/ActiveRecordが解釈するSQLプレースホルダの書き方」として不正・不適切な記述になっており、以下のような問題があったと考えられます:

  • Rails がサポートしていない/誤解を招く SQL プレースホルダの書き方
  • where などに渡すバインドパラメータの書き方と異なる構文
  • 実際に真似して書くとエラーになる、または意図しないSQLが生成される

このPRでは、そうしたプレースホルダ表記を、Railsで一般的かつ正しい書き方に修正しています。例として、以下のような修正が行われたと推測できます(イメージ):

ruby
# 修正前(無効・誤ったSQLプレースホルダの例)
Post.where("title = ? AND comments_count > :count", "hello", count: 5)

# 修正後(Railsで有効かつ推奨される形)
Post.where("title = ? AND comments_count > ?", "hello", 5)
# あるいは、名前付きバインドを正しく使う例:
Post.where("title = :title AND comments_count > :count", title: "hello", count: 5)

実際には3行追加・3行削除の非常に小さな修正で、コメントに記載されたサンプルコード内の「?」「:name」などの使い方が、Railsが期待する形に合わせて調整されています。


  1. 影響範囲・注意点
  • 実行コード・挙動への影響:

    • 実装ロジックやパブリックAPIは一切変更されていません。
    • ランタイムの挙動、既存アプリケーションへの影響はありません。
  • 影響があるのは:

    • Active Record finder メソッド (find, find_by, where など) のドキュメントを見てコードを書く開発者
    • サンプルコードをそのままコピペしていた場合、これまでのドキュメントはエラーを出していた/動作しなかった可能性があり、今回の修正によって「正しく動くサンプル」になります。
  • 注意点:

    • 古いドキュメントやブログ記事などで、今回修正前の誤った例を引用している場合、それらを信じて実装するとエラーになる可能性があるため、公式ドキュメントの最新版に合わせて修正するのが望ましいです。
    • Railsのwhereやfinder系メソッドでプレースホルダを使う場合は、
      • 「全て ? を使う」
      • または「全て :name を使う」
        のどちらかに統一し、混在させないのが安全です。

  1. 参考情報 (あれば)
  • Active Record クエリインターフェイスガイド(WHERE 条件の書き方・バインドパラメータ)
    https://guides.rubyonrails.org/active_record_querying.html#conditions
  • プレースホルダの正しい使い方の例:
    • Post.where("title = ? AND created_at > ?", "hello", 1.week.ago)
    • Post.where("title = :title AND created_at > :time", title: "hello", time: 1.week.ago)

#56558 Wrap setting ActionController::Live config in load hook

マージ日: 2026/1/12 | 作成者: @adrianna-chang-shopify

  1. 概要 (1-2文で)
    ActionController::Live の設定処理を load hook で包むことで、「実際に ActionController::Live を使うまでロードしない」ように遅延ロード化した PR です。これにより、単に ActionController をロードしただけでは Live 機能一式が読み込まれず、不要なオートロードや依存の読み込みを避けられます。

  1. 変更内容の詳細

※元 PR 本文の This Pull Request changes [REPLACE ME] はテンプレ修正漏れですが、ファイル差分から意図は推定できます。

(1) ActionController::Live の設定を load hook 内に移動

これまで:

  • ActionController::Railtie の初期化処理の中で ActionController::Live に対する設定が直接行われていた
    → 結果として、ActionController がロードされるタイミングで ActionController::Live も一緒にロードされてしまう

変更後:

  • ActionController::Railtie 側では、ActionController::Live 用の設定を「ActionController::Live がロードされたタイミングで実行する」ように、ActiveSupport.on_load(:action_controller_live) 形式の load hook でラップ
  • 実際に ActionController::Live を参照したり include したりしてロードされた時点で、初めて設定処理が走る

イメージとしては、例えば以下のような形になります(あくまでイメージコード):

ruby
# 以前 (イメージ)
module ActionController
  class Railtie < Rails::Railtie
    initializer "action_controller.live_config" do |app|
      ActionController::Live.some_config = app.config.action_controller.some_live_config
    end
  end
end

# 変更後 (イメージ)
module ActionController
  class Railtie < Rails::Railtie
    initializer "action_controller.live_config" do |app|
      ActiveSupport.on_load(:action_controller_live) do
        self.some_config = app.config.action_controller.some_live_config
      end
    end
  end
end

これにより、ActionController 本体のロードと ActionController::Live のロードが疎結合になり、「使われるまで Live をロードしない」形にできます。

(2) ActionController::Live 本体の微修正

actionpack/lib/action_controller/metal/live.rb に 2 行追加されており、load hook から設定を受け取るために必要な仕掛けが入っています。

典型的なパターンとしては:

  • モジュール/クラスがロードされたタイミングで ActiveSupport.run_load_hooks(:action_controller_live, self) を呼ぶ
  • これにより、ActionController::Railtie 側で登録しておいた on_load(:action_controller_live) ブロックが実行される

イメージ:

ruby
module ActionController
  module Live
    # live の実装…

    ActiveSupport.run_load_hooks(:action_controller_live, self)
  end
end

このようなパターンになっている可能性が高いです。

(3) CHANGELOG とガイドの更新

  • actionpack/CHANGELOG.md
    • ActionController::Live の設定が load hook 経由の遅延ロードになったことが記述されている
  • guides/source/configuring.md
    • ActionController::Live に関する設定の説明が、最新の挙動(load hook での設定)に合わせて 1 行追記されている

  1. 影響範囲・注意点

影響範囲

  • 主に ActionController::Live(SSE など)を利用しているアプリケーション
  • ActionController::Live の設定を Railtie/initializer 経由でいじっているライブラリやエンジン

典型的な Rails アプリで、ActionController::Live を特に使っていない場合は、挙動としてはほぼ無影響で、むしろ:

  • 不要なクラスのロードが減る
  • ブート時間やメモリフットプリントがわずかに改善する可能性

といったプラスの効果が見込まれます。

注意点

  1. ActionController::Live に依存した初期化処理

    • もしアプリや gem が「ブート時に ActionController::Live が必ず読み込まれている」ことを前提にしていた場合、
      今回の変更によって、その前提が崩れます。

    • 例:

      • initializer で ActionController::Live.some_config に直接アクセスしている
      • Railtie の initializerActionController::Live のクラスメソッドを呼んでいる
    • このような場合は、自前でも ActiveSupport.on_load(:action_controller_live) を使う形に書き換える必要があります:

      ruby
      # config/initializers/live_config.rb
      ActiveSupport.on_load(:action_controller_live) do
        self.some_config = "value"
      end
  2. ロード順に依存したコード

    • 以前は「ActionController がロードされた時点で ActionController::Live もロードされる」ため、
      ActionController のロード完了をもって Live の存在を前提にしていたコードがあれば、挙動が変わる可能性があります。
    • Rails の推奨パターンどおり load hook を使っていれば問題になりませんが、
      内部実装に依存していたコードは壊れる可能性があります。

  1. 参考情報 (あれば)
  • この PR は #56393 のフォローアップであり、「ActionController::Live 周辺の設定・ロードの整理」の一環
  • Rails では以下のような load hook パターンが広く使われています:
    • ActiveSupport.on_load(:action_controller) { ... }
    • ActiveSupport.on_load(:active_record) { ... }
  • 同様のパターンで、自前のコードでも「特定コンポーネントがロードされたタイミングで設定を適用する」ことが可能であり、
    ActionController::Live もそれに揃えられた形です。

#56580 Make CSRF header-only protection compatible with local installs using HTTP

マージ日: 2026/1/12 | 作成者: @rosa

  1. 概要 (1-2文で)
    CSRF の「ヘッダーのみ保護(header‑only protection)」を使っている Rails アプリでも、HTTPS を使っていないローカル環境(LAN 内アクセスなど)で非 GET リクエストが正しく通るようにする変更です。ブラウザが Sec-Fetch-Site ヘッダーを送れない「非 Secure Context」環境向けの互換性改善で、Origin チェックは引き続き行われます。

  1. 変更内容の詳細

背景

  • CSRF の header-only 方式では、ブラウザが送る Sec-Fetch-Site 等のヘッダーを使って「このリクエストがどこから来たか」を判定します。
  • しかし、HTTP で提供されるローカル・インストール(localhost ではなく、LAN 内 IP やホスト名など)では、多くのブラウザが「Secure Context」とみなさず、Sec-Fetch-Site ヘッダーを送信しません。
  • その結果、非 GET リクエスト(POST, PATCH, PUT, DELETE 等)が「CSRF ヘッダーが足りない」とみなされ、header-only モードだと拒否されてしまっていました。
  • Basecamp の fizzy でこの問題が起き、そこでの修正を Rails 本体に取り込んだのが今回の PR です。

具体的な挙動変更

変更のポイントは:

Sec-Fetch-Site ヘッダーが付かない場合でも、HTTP で動いていて、かつアプリが force_ssl で HTTPS を強制していないなら、CSRF ヘッダーだけを理由に非 GET リクエストを落とさない」

という条件分岐を RequestForgeryProtection に加えたことです。
※ 正確な Ruby コードは差分からの推測ですが、概念的には以下のようなロジックです。

ruby
# 疑似コードイメージ(実際のコードは多少異なる可能性があります)
def valid_request_origin?
  # 1. Origin チェックは常に実施
  return false unless valid_origin? # 例: same-origin かどうかなど

  # 2. header-only モードで、Sec-Fetch-Site が無い場合の特例
  if header_only_csrf_protection? &&
     request.sec_fetch_site.nil? &&
     request.scheme == "http" &&
     !force_ssl_configured?
    # ローカル HTTP かつ SSL 強制なし → 許可
    return true
  end

  # 3. 通常は Sec-Fetch-Site などヘッダー情報に基づく既存ロジックで判定
  valid_based_on_fetch_metadata_headers?
end

ここでのポイント:

  • Sec-Fetch-Site が無い」= ブラウザが Secure Context ではないと見なしている場合が多い。
  • request.scheme == "http" かつ force_ssl 無効 → 「開発・ローカル・オンプレの HTTP 運用を想定した特別扱い」とみなす。
  • それ以外(本番や HTTPS で運用しているケースなど)は従来どおり、Sec-Fetch-Site を使った保護を厳格に運用。

テストとドキュメント

以下のファイルが更新されています:

  • actionpack/lib/action_controller/metal/request_forgery_protection.rb
    上記条件分岐(HTTP + no force_ssl + missing Sec-Fetch-Site の場合の特例許可)を実装。

  • actionpack/test/controller/request_forgery_protection_test.rb
    新挙動をカバーするテストが追加。

    • HTTP かつ Sec-Fetch-Site なしでも、header-only モードで非 GET が通るケース
    • HTTPS / force_ssl 有効の場合は従来どおりブロックされるケース を検証していると考えられます。
  • railties/test/application/middleware/session_test.rb / test_runner_test.rb
    セッション・テストランナー周辺で、Sec-Fetch-Site がない環境のふるまいに関する期待値を新仕様に合わせて調整。

  • actionpack/CHANGELOG.md
    Action Pack の変更履歴に、

    • 「CSRF header-only protection が HTTP ローカルインストールでも動作するようになった」
    • Origin チェックは維持される」 といった内容のエントリが追加。

  1. 影響範囲・注意点

影響範囲

  • 対象となるのは CSRF の header-only 保護を有効にしている Rails アプリ で、かつ
    • HTTP でアクセスされている
    • config.force_ssl = false(もしくは未設定) の環境です。
  • 主に以下のようなシナリオで挙動が改善されます:
    • オンプレミスやローカルネットワーク内での HTTP アクセス
    • プライベート IP / カスタムホスト名などで public HTTPS を立てていない環境
    • 開発用に header-only モードを試しているが、ブラウザが Sec-Fetch-Site を付けずに困っていたケース

セキュリティ上の注意点

  • この緩和は HTTPS を強制していない HTTP 環境 に限定されており、
    • そもそも HTTPS を使っていない時点で通信路が安全でない
    • そのような前提のもとで「利便性と互換性」寄りの挙動を取る
      という設計方針になっています。
  • Origin チェックは「常に行われる」と明示されており、
    • Origin が想定外ドメインの場合のブロック
    • Same-Origin であることを前提にした CSRF 防御 は維持されます。
  • 本番運用では、依然として
    • HTTPS と config.force_ssl = true
    • 非 header-only モードでのトークンベース CSRF(またはそれとの併用) を推奨すべきです。
      この変更はあくまでローカル/レガシー HTTP 環境の「壊れない挙動」を整えるものです。

互換性

  • force_ssl を有効にしている(または HTTPS で運用している)アプリでは、従来の CSRF 挙動から変化しないように条件分岐されているため、互換性影響は限定的です。
  • header-only モードをすでに HTTP ローカル環境で使っていて、Sec-Fetch-Site の欠如によるエラーをワークアラウンドしていた場合は、そのワークアラウンドが不要になる可能性があります。

  1. 参考情報 (あれば)

#56554 Fix invalid option: --trace error when running railties tests

マージ日: 2026/1/12 | 作成者: @yujiteshima

  1. 概要 (1-2文で)
    railties ディレクトリで bundle exec rake test --trace を実行した際、テスト完了後の終了時に invalid option: --trace が発生していた問題を修正するPRです。test:isolated 実行後に ARGV をクリアすることで、Minitest の at_exit フックが Rake 用のオプション --trace を誤って解釈しないようにしています。

  1. 変更内容の詳細

問題の原因

発生していた流れは以下の通りです:

  1. rake testtest:isolated タスクを実行
  2. test:isolatedtest/isolation/abstract_unit.rbrequire
  3. abstract_unit.rbactive_support/testing/autorunrequire
  4. autorun.rbMinitest.autorun を呼び出し、at_exit フックを登録
  5. プロセス終了時 (at_exit 実行時) に Minitest が ARGV をパース
  6. ARGV にはまだ Rake オプション --trace が残っていて、Minitest はこれを自分のオプションだと思ってパースしようとする
  7. Minitest は --trace をサポートしていないため invalid option: --trace で落ちる

つまり「テスト自体はすべて成功しているが、終了処理のところで Minitest が Rake 固有のオプションを解釈しようとしてコケる」という状態でした。

対応内容

railties/Rakefiletest:isolated タスクの ensure 節で ARGV をクリアするコードが追加されています。

イメージとしては次のような変更です(概念的なサンプル):

ruby
namespace :test do
  task :isolated do
    begin
      # ここで isolated テストを実行
      # require "test/isolation/abstract_unit"
      # ... テスト実行 ...
    ensure
      # ここで Rake のオプションを Minitest から隠す
      ARGV.clear
    end
  end
end

ポイント:

  • ensure で実行しているため、テスト中に例外が発生した場合でも必ず ARGV.clear が呼ばれます。
  • これにより、プロセス終了時点で ARGV が空になり、Minitest の at_exit フックが Rake 特有のオプション (--trace など) を見ることがなくなります。

  1. 影響範囲・注意点
  • 直接の影響範囲は railtiestest:isolated タスクおよび、rake test 実行時に呼ばれる isolated テストです。
  • bundle exec rake test --trace を実行しても、終了時に invalid option: --trace が出なくなります。
  • ARGV をクリアするため、test:isolated タスク内/またはその後に「グローバルな ARGV の中身」に依存しているコードがあれば影響を受けますが、通常の Rails / railties テストタスクでは ARGV 直接参照は前提としておらず、影響はほぼないと考えられます。
  • 修正はテスト専用の Rake タスクに限定されており、本番コードや通常のアプリ実行には影響しません。

  1. 参考情報 (あれば)
  • 対応する Issue: Fixes #56448

  • 再現コマンド:

    bash
    cd railties
    bundle exec rake test --trace

    この PR 適用前: テスト完了後に invalid option: --trace エラーで終了
    この PR 適用後: 正常終了 (テスト結果のみ出力)


#56574 Clean up ENV leaks continued

マージ日: 2026/1/12 | 作成者: @zzak

  1. 概要 (1-2文で)
    このPRは、テストやRakeタスク実行時に環境変数 (ENV) が他テストやプロセスに漏れないようにするためのクリーンアップ対応を進めたものです。主に Rails のテストコード側で ENV の設定/復元方法を整理し、環境依存の副作用を減らしています。

  1. 変更内容の詳細

※PR本文には具体的コードは掲載されていませんが、変更ファイルから推測できる範囲で解説します。

全体方針

  • ENV を直接書き換えるテスト・タスクを見直し、「テスト前に設定 → テスト後に必ず復元」というパターンを徹底。
  • それにより、あるテストケースで設定した環境変数が他のテストに影響したり、CI環境の実際の環境変数を汚染したりする問題を防止。
  • #56563 をクローズしていることから、「ENV leak(環境変数の漏れ)」に関する既知の不具合/不安定テストの続きの修正と考えられます。

activerecord/lib/active_record/railties/databases.rake

  • DB 関連 Rake タスクで、環境変数を参照・設定する箇所を整理。
  • 想定される修正:
    • 必要なキーだけを ENV から読むようにする
    • もしくは ENV["XXX"] ||= ... のような「上書きしうる」書き方をやめる/安全な形に変更
  • 目的は、Rake 実行時に既存の環境変数を不要に変更しないことです。

railties/test/... 以下のテスト群

対象ファイル:

  • railties/test/application/asset_debugging_test.rb
  • railties/test/application/configuration_test.rb
  • railties/test/application/view_reloading_test.rb
  • railties/test/commands/server_test.rb
  • railties/test/generators/action_mailbox_install_generator_test.rb
  • railties/test/isolation/abstract_unit.rb

これらは Rails アプリケーション/コマンド/ジェネレータをテストする「統合寄りのテスト」が中心で、環境変数に強く依存しがちな部分です。

典型的に行われている変更は次のようなパターンです:

(1) ENV をテストごとに退避・復元

ruby
def setup
  super
  @original_env = ENV.to_hash
end

def teardown
  ENV.replace(@original_env)
  super
end

あるいは、特定のキーだけを退避・復元するスタイル:

ruby
def with_env(var, value)
  old = ENV[var]
  ENV[var] = value
  yield
ensure
  ENV[var] = old
end

これにより、テスト中に ENV["RAILS_ENV"]ENV["WEBPACKER_DEV_SERVER"] などを変更しても、他のテストに影響しません。

(2) ENV の一時的な変更をヘルパー経由に統一

railties/test/isolation/abstract_unit.rb などで、テスト間で再利用される「隔離実行」の仕組みに、環境変数を扱うヘルパーが追加・拡張されている可能性があります。

想定されるコードイメージ:

ruby
def run_in_isolation_with_env(env_overrides)
  original_env = ENV.to_hash
  ENV.update(env_overrides)
  yield
ensure
  ENV.replace(original_env)
end

これを用いて、各テストファイルでバラバラにやっていた ENV 操作を統一的に扱えるようにしていると考えられます。

(3) テストが依存する ENV の明示化

  • asset_debugging_test / view_reloading_test / configuration_test などで、
    • 「特定の ENV が設定されているときに、Rails の設定や挙動がどう変わるか」をテストしている部分の記述を整理。
    • 具体的には ENV["RAILS_ENV"], ENV["RAILS_ENV"] = "production" などを直接書いていた箇所を、ヘルパーメソッドや with_env ブロックに包んで安全に実行するように変更した可能性が高いです。

(4) server_test / generator_test の CLI 実行まわり

server_test.rbaction_mailbox_install_generator_test.rb は、実際に rails server やジェネレータコマンドをシェル的に呼び出すテストが多く、RAILS_ENVPORT, RACK_ENV などを環境変数で切り替えていることがあります。

  • 修正内容の方向性:
    • コマンド実行前に環境変数をセットする処理をヘルパーにまとめる
    • 実行後に必ず元に戻すようにする
    • これにより、1つのテストが別のテストのポートやモードを壊すことを防ぎます。

  1. 影響範囲・注意点
  • 影響範囲

    • 変更はほぼテストコードと Rake タスクの一部に限定されており、通常のアプリケーション実行パスには直接の仕様変更はなさそうです。
    • ただし、テストが前提としていた「ENV の状態」に依存していた場合、その前提が明示化されたり、より厳密になったことで、既存の不安定テスト(出たり出なかったりするテスト)が安定する可能性があります。
  • Rails 開発者(Rails 本体にパッチを送る側)への注意点

    • 新たにテストを書く際は、ENV を直接グローバルに書き換えるのではなく、今回整理された「環境変数を一時的に変更して元に戻すヘルパー」を利用することが推奨されます。
    • ENV をテスト中に変更するときは、「必ず元の値に戻す」か「コピーして差し替える」というパターンを守らないと、CI での環境依存の失敗を招きます。
  • Rails を利用しているアプリ開発者への影響

    • アプリケーション側のコードや挙動への直接の互換性影響はほぼありません。
    • 将来的に、Rails 本体のテストがより安定することで、CI 環境における Rails 自体のテストフレームワークの信頼性が上がるという、間接的なメリットがあります。

  1. 参考情報 (あれば)
  • このPRは issue / PR #56563 の「ENV leak」対応の続きとして位置付けられており、ENV の副作用が問題になっていた点を段階的に解消する流れの一環です。

  • Rails のテストで ENV 周りを安全に扱う典型パターン(参考イメージ):

    ruby
    def with_modified_env(options)
      old_env = ENV.to_hash
      ENV.update(options)
      yield
    ensure
      ENV.replace(old_env)
    end
    
    test "respects FOO setting" do
      with_modified_env("FOO" => "bar") do
        assert_equal "bar", ENV["FOO"]
        # テスト本体
      end
    end
  • 実際の詳細な変更内容やユーティリティメソッド名は、該当ファイルの差分を直接確認すると正確に把握できますが、全体としては「ENV の扱いの安全性・一貫性を高める」リファクタリング PR と理解すると良いです。


#56583 Update comment as Proc support is removed in revision [ci skip]

マージ日: 2026/1/12 | 作成者: @tahsin352

  1. 概要 (1-2文で)
    config.revision に関するコメント文を、Proc(ラムダ)による指定サポートが削除された現状に合わせて修正したドキュメント的変更のPRです。コードの挙動は変わらず、説明コメントのみが最新仕様に追従しています。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル: railties/lib/rails/application.rb
  • 変更内容: config.revision に関するコメントの1行を書き換え

元々は、#56508 で config.revision の Proc サポートが削除されたにもかかわらず、コメント内には「Proc を使える」旨の説明が残っていました。
このPRでは、その古い説明を削除(または書き換え)し、「config.revision は Proc を受け付けない」現在の仕様に沿ったコメント内容に更新しています。

イメージとしては、例えば以下のような古いコメント:

ruby
# config.revision can be a String or a Proc that returns the revision.
config.revision = ...

が、Proc 記述を含まない形に修正される、という種類の変更です(実際の文言はRails本体を参照)。

コードレベルの挙動 (config.revision の型チェックや利用箇所) は一切変更されておらず、コメントのみの1行差分となっています。


  1. 影響範囲・注意点
  • 実行時挙動: 変更なし
    • すでに #56508 で Proc サポートは削除済みであり、このPRはその仕様にコメントを合わせただけです。
  • 主な影響:
    • Rails本体のコメントを読んで設定を書く開発者に対して、誤った情報(「Procを使える」と思い込むこと)を防ぐ効果があります。
  • 注意点:
    • もし以前のバージョンのRailsからの移行で config.revision = -> { ... } のような設定をしている場合、このPRではなく #56508 の時点で既に動かなくなっています。
    • その場合は、config.revision を明示的な文字列など、現行サポートされている形式に書き換える必要があります。

  1. 参考情報 (あれば)
  • 関連PR:
    • #56508 — config.revision における Proc サポートを削除したPR(今回のコメント修正の元になった変更)
  • 対象機能:
    • Rails::Application の設定項目 config.revision
      デプロイリビジョン・バージョン情報の表現に使われることがある設定で、現状はコメントに記載された型・利用方法のみがサポート対象となります。

#56579 Fix reverting change_table bulk: true with indexes

マージ日: 2026/1/12 | 作成者: @fatkodima

  1. 概要 (1-2文で)
    change_table bulk: true を使ったマイグレーションにインデックス操作が含まれている場合、rails db:rollback などでのリバートが正しく動かない不具合を修正する PR です。SchemaStatementsCommandRecorder の挙動を調整し、テストを更新して期待どおりに巻き戻せるようにしています。

  1. 変更内容の詳細

※PR本文と差分が少ないため、Rails のこれまでの実装と関連 Issue/PR から推測を含みますが、方向性としては以下のような修正です。

背景: change_table bulk: true とインデックス

Rails では、以下のように change_tablebulk: true を付けると、アダプタがサポートしていれば ALTER TABLE をまとめて実行してくれます:

ruby
change_table :users, bulk: true do |t|
  t.string :name
  t.index :name
end

ところが、ここにインデックス操作(t.index, t.remove_index など)が含まれる場合、change マイグレーションを rollback した際に

  • CommandRecorder が正しく逆操作を記録できない
  • あるいは SchemaStatements 側で bulk: true な操作の中の index を正しく分解できない

といった問題があり、結果としてマイグレーションを戻せない/誤った SQL が生成される、というバグが報告されていました(#56573, #56578 のフォローアップ)。

主な修正ポイント

差分は 3 ファイル・7行追加/7行削除と小さいですが、位置的に見ると以下のような内容が考えられます:

  1. SchemaStatements#change_table の修正

    • bulk: true のとき、テーブル変更のブロック内に含まれるインデックス関連のコマンドをどう扱うかを調整。

    • 具体的には、bulk: true でも「インデックスの追加・削除」をリバーシブルに扱える形で CommandRecorder に記録できるようにしている可能性が高いです。

    • 例: 以下の change

      ruby
      def change
        change_table :users, bulk: true do |t|
          t.string :name
          t.index :name
        end
      end

      rollback したときに

      ruby
      change_table :users, bulk: true do |t|
        t.remove_index :name
        t.remove :name
      end

      に対応するような「逆操作」が確実に構成されるように修正されています。

  2. ActiveRecord::Migration::CommandRecorder の修正

    • change_table とインデックス系メソッドの組合せに対する invert_* のロジックを調整。
    • たとえば add_index / remove_index の逆操作を生成する際、bulk: true なコンテキストでも正しく解釈し、逆順で実行できるようにしています。
    • change_table 自体の記録形式([:change_table, table, options, &block] のような形)に対して、インデックス操作を落とさず、かつ逆操作に変換可能な形に統一した可能性があります。
  3. テストの追加・修正 (migration_test.rb)

    • 再現ケースに近いマイグレーションをテスト化しており、以下のようなケースがカバーされていると考えられます:
      • change_table :users, bulk: true でカラム追加 + インデックス追加を行う change マイグレーションを migraterollback してもエラーにならない
      • ロールバック後にインデックスもカラムも存在しないこと
    • 既存テストの期待値を、今回の修正に合わせて微調整している部分もあります (+3/-3 行の変更)。

  1. 影響範囲・注意点
  • 影響を受けるケース

    • change_table bulk: true を利用しており、その中で t.index, t.remove_index などインデックス関連の操作を行っているマイグレーション。
    • 特に change メソッドで定義していて、rails db:rollbackrails db:migrate:down を行うケース。
  • 期待できる改善

    • これまでロールバックに失敗していた/不正な SQL を発行していたようなマイグレーションが、問題なく往復可能になります。
    • change_table bulk: true を安心して使いやすくなります。
  • 注意点 / 確認したほうがよいこと

    • 既存プロジェクトで、問題のあるマイグレーションをすでに本番に適用済みの場合、そのマイグレーションを「今からロールバックする」際の挙動が変わる可能性があります。
      • 本番前に、開発・ステージング環境で該当マイグレーションの migrate / rollback を試して問題ないか確認した方が安全です。
    • アダプタ固有の挙動(特に MySQL / PostgreSQL / SQLite など)について、bulk: true のサポート状況が異なるため、DB ごとに挙動確認をしておくのが無難です。
    • #56578 の変更とセットで動作が安定する修正なので、Rails を部分的にパッチ適用している場合は、両方の差分を適用する必要があります。

  1. 参考情報 (あれば)

これらを読むと、どのようなマイグレーションでエラーが起きていたか、再現コードとともに確認できます。


#56578 Fix reverting change_table bulk: true with table names prefixes and suffixes

マージ日: 2026/1/11 | 作成者: @fatkodima

  1. 概要 (1-2文で)
    change_table bulk: true を使ったマイグレーションを「テーブル名の prefix / suffix を使っている環境で revert する」ときに誤動作していた問題を修正した PR です。ActiveRecord::Migration::CommandRecorder がテーブル名を正しく扱えていなかった点が直され、対応するテストが追加されています。

  1. 変更内容の詳細

問題の背景

  • Rails では config.active_record.table_name_prefix / table_name_suffix を設定すると、モデルに対応するテーブル名に自動的に接頭辞・接尾辞が付与されます。
    • 例: self.table_name_prefix = "tenant_" があると userstenant_users
  • change_table :users, bulk: true do |t| ... end のようなマイグレーションを revert するとき、内部的には ActiveRecord::Migration::CommandRecorder が「記録されたコマンド」を元に逆操作を生成します。
  • しかし「prefix / suffix 付きのテーブル名 + bulk: truechange_table」という組み合わせのとき、この逆操作生成でテーブル名が正しく扱われず、revert / rollback が壊れる(例: 間違ったテーブル名を参照する、あるいはエラーになる)不具合がありました。
  • この PR はその不具合報告 #56573 に対応する修正です。

実際の修正点

変更ファイルは 2 つだけです。

1. activerecord/lib/active_record/migration/command_recorder.rb (+1/-1)

CommandRecorder 内で change_table のコマンドを記録・反転するロジックの中に、1行の修正が入っています。

概ね以下のようなイメージの修正です(実際のコードは行数1の差分ですが、概念的にはこういう変更):

ruby
# 変更前(イメージ)
def invert_change_table(args, options = {})
  table_name = args.first
  # ここで table_name に prefix/suffix を考慮しない扱いがあった
end

# 変更後(イメージ)
def invert_change_table(args, options = {})
  table_name = args.first
  # prefix/suffix が付与されたテーブル名でも
  # 正しく逆操作を生成できるように扱いを修正
end

実際には 1 行の置き換えで、

  • 記録された change_table の引数(テーブル名)の扱い方
  • もしくは options の構造(特に bulk: true 時)
    のどちらか/両方が、prefix / suffix の存在を前提に安全に扱えるように修正されています。

bulk: true 時は、change_table ブロック内部の「複数のカラム追加・削除・index 変更など」をまとめて一つの操作として記録・反転しようとするため、ここでのテーブル名解釈の不一致が rollback 時に露呈していました。

2. activerecord/test/cases/migration_test.rb (+26/-0)

この不具合を再現し、修正を担保するためのテストが追加されました。
テストの内容は概ね以下のようなシナリオになっているはずです(擬似コード):

ruby
class ChangeTableWithPrefixTest < ActiveRecord::Migration::Current
  def change
    # 前提として prefix/suffix 設定を有効にした状態で
    change_table :users, bulk: true do |t|
      t.string :name
      t.integer :age
    end
  end
end

# テスト内容イメージ
def test_revert_change_table_with_prefix_and_bulk
  # prefix/suffix を設定
  ActiveRecord::Base.table_name_prefix = "tenant_"
  # ActiveRecord::Base.table_name_suffix = "_2026" などの suffix もテストしている可能性あり

  # マイグレーションを適用
  ChangeTableWithPrefixTest.migrate(:up)

  # ここでテーブルにカラムが追加されていることを確認
  assert column_exists?(:users, :name)
  assert column_exists?(:users, :age)

  # revert(または migrate(:down)) を実行できることを確認
  ChangeTableWithPrefixTest.migrate(:down)

  # 正しくカラムが戻されている(テーブル名解決もエラーにならない)ことを確認
  assert_not column_exists?(:users, :name)
  assert_not column_exists?(:users, :age)
end

実際には、

  • CommandRecorderchange_table ... bulk: true をどのように記録するか
  • その記録を revert した際に prefix/suffix 付きテーブルにも正しく適用されるか
    を検証するテストになっています。

  1. 影響範囲・注意点
  • 影響を受けるのは次の条件を「すべて」満たす場合です:
    • change_table を使ったマイグレーションがある
    • bulk: true オプションを付けている
    • Rails アプリで table_name_prefix / table_name_suffix を設定している、または一部モデルが独自に prefix/suffix を使っている
    • そのマイグレーションを revertrollback などで逆適用する可能性がある
  • 上記に該当するアプリケーションでは、この PR が入る前の Rails バージョンでは rollback が失敗したり、誤ったテーブルに対して操作しようとする危険がありました。
  • PR マージ後のバージョンでは、bulk: true をつけた change_table でも、prefix/suffix を含めて正しく revert できるようになります。
  • 既存マイグレーションの書き方を変える必要はなく、フレームワーク側の不具合修正のみです。ただし、過去に
    • この不具合を避けるために「bulk: true を使わない」「reversible / up/down で手作業の rollback を書く」
      といったワークアラウンドをしていた場合は、今後はそれらを簡略化できる可能性があります。

  1. 参考情報 (あれば)
  • 該当 PR: https://github.com/rails/rails/pull/56578
  • 関連 Issue: https://github.com/rails/rails/issues/56573
  • CommandRecorder のドキュメント(既存仕様の理解に有用):
    • ガイド: Active Record Migrations(特に「reversible」「reverting」セクション)
  • change_table bulk: true の振る舞いについては、Active Record Migrations ガイドの「Table Shortcuts」および bulk オプションの説明が参考になります。

#56571 Remove explicit Rake version constraint from Gemfile

マージ日: 2026/1/11 | 作成者: @yahonda

  1. 概要 (1-2文で)
    Rails の Gemfile から rake >= 13 という明示的なバージョン指定を削除し、Ruby 3.3 以降に同梱される Rake 13.1.0 に依存する形に整理した PRです。これにより、不要なバージョン制約をなくし、Ruby 本体のバンドルされた gem による標準構成に寄せています。

  1. 変更内容の詳細

変更点

  • Gemfile から Rake のバージョン指定を削除
    もともと以下のような記述(イメージ)があったものを:

    ruby
    # Gemfile(変更前イメージ)
    gem "rake", ">= 13"

    これを削除し、Rake は Ruby に同梱されているもの(または他の依存関係経由)に任せる形に変更しています。

  • Gemfile.lock からも対応する行を削除
    lock ファイル側からも Rake に関するエントリが 1 行減っています(バージョンピンや依存関係の記録が整理された程度の小変更)。

背景

  • Ruby 3.3 から、標準で rake 13.1.0 が bundled gem として同梱されています。
  • Rails プロジェクト側で「rake >= 13」という下限を明示する必要がなくなり、Ruby 側の保証に委ねられるようになりました。
  • これにより、Gemfile の責務を最小限にし、Ruby のデフォルト構成と重複する指定を排除しています。

  1. 影響範囲・注意点
  • 影響範囲

    • 開発環境・CI 環境ともに、Ruby 3.3 以降を前提とする場合は挙動はほぼ変わりません。Rake は Ruby に同梱された 13.1.0(あるいはそれ以降の同梱版)が使われます。
    • Rake を Gemfile で特定バージョンに固定していたわけではなく「>= 13」という緩やかな制約だったため、Ruby 3.3 で 13.1.0 が入っている状況では事実上同等です。
  • 注意点

    • Ruby 3.3 未満の環境
      • Ruby 2.x 系や 3.0〜3.2 系で Rails 本体を開発・ビルドしようとする場合、環境によっては十分なバージョンの Rake がインストールされていない可能性があります。

      • その場合は、利用者側で

        bash
        gem install rake -v ">= 13"

        のように Rake をインストールするか、ローカルのアプリケーションで Rake を明示的に Gemfile に追加する必要があります。

    • CI・開発ツールチェーン
      • CI イメージが Ruby 3.3 未満かつ Rake のバージョンが低い場合、タスク実行時に問題が出る可能性があります。Rails 本体の開発に Ruby 3.3 以上を用いることが事実上の前提になりつつある点に注意が必要です。

  1. 参考情報 (あれば)
  • Ruby 3.3 リリースノート(bundled gems の更新)
    https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released

    上記で rake 13.1.0 が同梱 gem として更新されたことが明記されています。

  • Bundled gems の扱いの一般的な注意点:

    • Bundler 使用時でも、標準添付/同梱 gem は Gemfile の指定がなければそのまま利用されます。
    • Gemfile に明示的に書かないことで、Ruby の将来バージョンで Rake が更新されても、Rails 側が不要に制約しなくて済む構成になります。

#56546 Fix Errors#added? with callback options in query

マージ日: 2026/1/9 | 作成者: @khasinski

  1. 概要 (1-2文で)
    Rails の ActiveModel::Errors#added? が、エラー追加時と同じコールバックオプション(allow_nil, if, unless など)を指定して問い合わせた場合に常に false になっていたバグが修正されました。これにより errors.adderrors.added? 間のオプション付き照合が正しく対称に動作するようになります。

  1. 変更内容の詳細

問題のあった挙動

ActiveModel::Errors#added? は、指定した属性・メッセージ・オプションに対応するエラーが既に登録されているかをチェックするメソッドですが、バリデーションのコールバック系オプション(例: allow_nil, if, unless)を渡した場合に、実際には存在しているエラーに対しても false を返していました。

ruby
errors.add(:name, :too_long, allow_nil: true)
errors.added?(:name, :too_long, allow_nil: true)  # 本来 true であるべきだが、false になっていた

この原因は ActiveModel::Error#strict_match? にありました。

  • 保存済みエラー側のオプションからは「コールバック/メッセージ関連のオプション」を除外して比較していた
  • しかし問い合わせ側(added? に渡したオプション)はそのまま比較に使っていた

つまり「保存時はオプションを一部削ぎ落としているのに、問い合わせ時は削ぎ落とさずに比較している」ため、ハッシュ比較が非対称になり、オプションを付けた問い合わせが常に一致しない状態になっていました。

今回の修正内容

strict_match? の実装を変更し、比較前に「保存されたエラー側」と「問い合わせオプション側」の両方から、コールバック/メッセージ関連のオプションを同じように取り除いた上で比較するように修正しています。

それにより、次のようなケースで期待どおり true が返るようになりました。

ruby
errors.add(:name, :too_long, allow_nil: true)
errors.added?(:name, :too_long, allow_nil: true)  # => true

テストの追加

activemodel/test/cases/errors_test.rb に以下のようなテストが追加され、allow_nil, if, unless などのオプション付きで added? が正しく動作することが検証されています(テストは複数ケースで 22 行追加)。

  • コールバックオプション付きで errors.add した場合に、同じオプションを付けて added? を呼んでも true になること
  • メッセージシンボル/メッセージ文字列の両方のパターン

  1. 影響範囲・注意点
  • 対象: ActiveModel::Errors#added? を、allow_nil, if, unless などのオプション付きで使用しているコード
  • 影響: これまで「実際には存在しているエラーを added? が見逃していた」ケースで、正しく true が返るようになります。
    • 例: 「まだこのエラーが追加されていないときだけ追加する」といったロジックが、より意図どおりに動くようになる。
  • 互換性:
    • 本来バグであった挙動の修正のため、正しいロジックを期待していたコードにとっては改善です。
    • もし「added? がバグで false を返すこと」を前提にして変なワークアラウンドをしていた場合は、そのワークアラウンドが不要になる(=挙動が変わる)可能性があります。

Rails のバリデーションフロー自体が変わるわけではなく、あくまでエラー状態を問い合わせるユーティリティメソッドの比較ロジックのみの修正なので、基本的には安全なバグフィックスと考えてよいです。


  1. 参考情報 (あれば)

#56564 Remove X-XSS-Protection from default headers

マージ日: 2026/1/9 | 作成者: @byroot

  1. 概要 (1–2文で)
    Railsがデフォルトで送出していた X-XSS-Protection レスポンスヘッダを削除する変更です。Rails 8.2 向けの設定・ガイドもそれに合わせて更新され、今後はこのヘッダを自動的には付与しません。

  1. 変更内容の詳細

2-1. デフォルトヘッダから X-XSS-Protection を削除

これまで Rails は ActionDispatch 経由でレスポンスに以下のようなヘッダをデフォルト付与していました(簡略イメージ):

ruby
config.action_dispatch.default_headers = {
  "X-Frame-Options" => "SAMEORIGIN",
  "X-XSS-Protection" => "0",
  ...
}

この PR では、X-XSS-Protection がデフォルトヘッダセットから削除されます。
実際のコード上は、railties/lib/rails/application/configuration.rb で管理されているデフォルトヘッダ定義から、このヘッダキー自体がなくなっています。

目的としては、もはやブラウザ側で意味のある効果を持たない(または非推奨になっている)ため、Rails が標準で付け続ける必要がない、という判断です。

2-2. 新規アプリ生成用テンプレートの更新

railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_2.rb.tt にも追記があり、Rails 8.2 の「新フレームワークデフォルト」イニシャライザのテンプレートに、X-XSS-Protection を削除する挙動が反映されました。

Rails 8.1 → 8.2 移行時に new_framework_defaults_8_2.rb が生成されると、そこに「X-XSS-Protection を使わない」ことを明示する記述(コメントや設定)が含まれる形になります。
(具体的には、「このバージョンからはデフォルトヘッダに X-XSS-Protection を含めない」といった説明コメントと、それに対応する設定コードが追加されているイメージです。)

2-3. ガイドドキュメントの更新

変更されたガイド:

  • guides/source/configuring.md

    • デフォルトヘッダの説明部分が更新され、X-XSS-Protection に関する記述が削除または調整されています。
    • 代わりに(あるいは併せて)、現在有効なデフォルトヘッダや、そのカスタマイズ方法が記載されています。
  • guides/source/security.md

    • X-XSS-Protection に関する節や説明が削除されています(-7 行)。
    • 「Rails の XSS 対策としてこのヘッダを使うべき」というような推奨はもはや行われません。

  1. 影響範囲・注意点

3-1. 実務上の影響

  • 新しい Rails アプリケーション

    • デフォルトで X-XSS-Protection がレスポンスに付かなくなります。
    • ただし、主要なモダンブラウザ(Chrome / Edge / Firefox / Safari)は既にこのヘッダを無視しているか、サポートをやめているため、実質的な挙動への影響はほぼありません。
  • 既存アプリのアップグレード(8.2 以降)

    • new_framework_defaults_8_2.rb を読み込み、config.load_defaults "8.2" 相当の設定に切り替えたタイミングで、このヘッダが自動的に付与されなくなります。
    • それまで独自に X-XSS-Protection を利用しており、レガシーブラウザを前提にした挙動を期待していた場合は、必要に応じて自前でヘッダを設定してください。

3-2. もし X-XSS-Protection をまだ使いたい場合

レガシー環境などで、どうしても維持したい場合は、config.action_dispatch.default_headers で明示的に設定できます:

ruby
# config/application.rb など
config.action_dispatch.default_headers.merge!({
  "X-XSS-Protection" => "1; mode=block"
})

もしくは Rack ミドルウェアや controller レベルで response.headers に直接設定することも可能です。

3-3. セキュリティ的な考え方の変化

  • Rails は X-XSS-Protection に依存するのではなく、サーバサイドエスケープ(ERBsanitize / 自動エスケープ)、content_security_policy などのよりモダンな仕組みを中心に XSS 対策を行う方針になっています。
  • X-XSS-Protection 自体は「古いブラウザの独自 XSS フィルタ用スイッチ」であり、現代のブラウザではほぼ役に立たない・場合によっては誤検知などの副作用を生むため、削除は妥当な方向と考えられます。

  1. 参考情報 (あれば)
  • Rails Guides(今回更新されたもの)
    • Configuring Rails Applications: guides/source/configuring.md
    • Security Guide: guides/source/security.md
  • 一般的な背景:
    • Chromium/Chrome は X-XSS-Protection を既に無視しており、MDN などでも非推奨として文書化済み。
    • 推奨される代替: Content-Security-Policy (CSP)、適切な HTML エスケープ、テンプレートエンジンの auto-escaping など。

この PR により、Rails が現状のブラウザ事情に合わせて不要なレガシーヘッダを整理し、よりモダンなセキュリティ戦略に寄せる一歩になっています。


#56251 Adds template-file rendering examples in the bug report test-template for ActionView

マージ日: 2026/1/9 | 作成者: @shivabhusal

  1. 概要 (1-2文で)
    Action View向けのバグ報告テンプレートに、「テンプレートファイルのレンダリング問題」を再現しやすくするための具体的な書き方・例が追加されました。これにより、View周りの不具合報告からすぐに実行可能なテストを作りやすくなり、再現性・解析効率の向上が期待できます。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル: guides/bug_report_templates/action_view.rb
  • 目的:
    • 「テンプレートファイルをどう用意し、どう render させてテストすればいいか」が分かるように、Action View 用のバグ報告テンプレートにガイドと例を追加。
    • issue 報告者が「実行可能な最小テストケース」を書きやすくする。

具体的には以下のような内容がテンプレートに含まれる形になります(構成イメージ):

  • テンプレートファイルの作成例

    • 例えば app/views/users/show.html.erb のようなファイルを、バグ報告用テストの中でセットアップする例が示される:
      ruby
      # 例: テスト内でテンプレートファイルを生成
      def setup
        super
        FileUtils.mkdir_p("#{Rails.root}/app/views/users")
        File.write(
          "#{Rails.root}/app/views/users/show.html.erb",
          <<~ERB
            <h1><%= @user.name %></h1>
          ERB
        )
      end
    • これにより「どのディレクトリにどんなファイルを置けば Action View が拾ってくれるのか」が明示される。
  • レンダリングのテスト例

    • コントローラ/ビューのレンダリングを実行する標準的なパターンをテンプレートに含めることで、報告者がそれをコピペして最小ケースを作れるようになっている想定:
      ruby
      test "renders user show template" do
        @controller = UsersController.new
      
        get :show, params: { id: 1 }
      
        assert_response :success
        assert_includes @response.body, "Alice"
      end
    • もしくは ActionView::Base を直接使ったレンダリング例が入っている可能性もあり、
      ruby
      view = ActionView::Base.with_empty_template_cache.new(
        ActionView::LookupContext.new(["#{Rails.root}/app/views"]),
        {}, # assigns
        ApplicationController.new
      )
      
      result = view.render(template: "users/show")
      
      assert_includes result, "Alice"
      のように、テンプレートパスの指定方法や LookupContext のセットアップ方法を示す例が含まれている形です。
  • バグ報告者へのガイド文言の追加

    • 「テンプレートがどこにあるか」「どのテンプレートを render しているか」「どのようなパラメータ/インスタンス変数で再現するか」を明示するよう促すコメントがテンプレート内に追加。
    • 例:
      • 使用しているテンプレートパス (users/show, posts/index など)
      • 再現に必要なローカル変数・インスタンス変数
      • レンダリング方式 (render :template, render :partial, render inline: など)
      • 期待する出力 vs 実際の出力 の記述

これらにより、報告者は「テンプレートファイルをどうテストに組み込むか」まで含めたサンプルを元に、自分の不具合ケースを書きやすくなります。


  1. 影響範囲・注意点
  • 影響範囲

    • 既存コードの挙動には影響せず、Rails 本体のランタイムには変更なし。
    • 影響するのは「Rails ガイドに含まれる Action View バグ報告テンプレート」を利用する開発者・コントリビューターのみ。
    • 今後の Action View 関連 issue で、テンプレートファイルを含む再現用テストが添付されやすくなることで、コアチームやメンテナが不具合を再現しやすくなる。
  • 注意点

    • あくまでガイド・テンプレートの更新なので、既存のバグ報告テンプレート(独自で使っているもの)には自動的に反映されない。
    • 自分のプロジェクトで GitHub Issue template やバグ再現用スクリプトを運用している場合は、この PR のテンプレート内容を参考に「テンプレートファイルのセットアップ&レンダリング例」をローカルなテンプレートにも取り込むと効果的。
    • Rails のバージョンによって ActionView::BaseLookupContext の使い方が若干変わることがあるため、自分の利用バージョンに合わせて微調整が必要な場合があります(この PR は最新の Rails main / edge を前提)。

  1. 参考情報 (あれば)
  • PR: https://github.com/rails/rails/pull/56251
  • 類似のバグ報告テンプレート (Active Record, Action Pack など) もあるため、複合的な問題(例: コントローラ + ビューの組み合わせ)の場合は他のテンプレートも併用すると、より再現性の高い報告が作れます。
  • 独自に再現用スクリプトを用意する場合でも、「テスト内でテンプレートファイルを生成してから render する」というパターンは、そのまま応用できます。

#56561 Deprecate protect_from_forgery without explicit strategy

マージ日: 2026/1/8 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Rails 8.2 で protect_from_forgery を引数なしで呼び出す書き方が非推奨になり、今後は必ず明示的に戦略(with: :exception など)を指定することが推奨されます。これにより、config.action_controller.default_protect_from_forgery との挙動の不一致をなくし、CSRF 対策の設定を明確にするのが目的です。

  1. 変更内容の詳細

背景となる問題

現状の挙動:

  • コントローラで明示的に呼ぶ場合:
ruby
class ApplicationController < ActionController::Base
  protect_from_forgery  # 引数なし
end

→ デフォルトは with: :null_session として動作。

  • 一方、設定で
ruby
config.action_controller.default_protect_from_forgery = true

を有効にした場合、内部的には

ruby
protect_from_forgery with: :exception

相当として動く。

この結果、以下のような「どこで有効にしているか」によってデフォルト戦略が変わる不整合が生じていました。

この PR での主な変更点

  1. protect_from_forgery の引数なし呼び出しを非推奨に

    • protect_from_forgery をオプションなしで呼ぶと、deprecation warning が出るようになります。
    • メッセージの趣旨:
      • 将来のバージョンでは、デフォルト戦略が変わる可能性がある
      • そのため、必ず with: を明示してください、というガイダンス。

    想定される推奨コード例:

    ruby
    class ApplicationController < ActionController::Base
      # 例1: 例外を投げる従来型
      protect_from_forgery with: :exception
    
      # 例2: API でよく使うセッションなし
      # protect_from_forgery with: :null_session
    
      # 例3: 古い互換のための reset_session
      # protect_from_forgery with: :reset_session
    end
  2. config.action_controller.default_protect_from_forgery 周りの整理

    • この設定を有効にすると、これまで通り protect_from_forgery with: :exception を自動的に適用しますが、
    • ガイド/ドキュメント側に「デフォルトの戦略は :exception であること」「引数なし呼び出しは非推奨であること」が明記されました。

    config/initializers/new_framework_defaults_8_2.rb テンプレートにも、この挙動に関するコメントと設定例が追記されています。

  3. テストの追加・更新

    • protect_from_forgery を引数なしで使った場合に deprecation が発火することを確認するテストが追加。
    • default_protect_from_forgery 設定との組み合わせや既存挙動を壊していないことを確認するテストも強化。
  4. CHANGELOG / ガイドの更新

    • actionpack/CHANGELOG.md に、この非推奨変更が追記されています。
    • guides/source/configuring.md に CSRF 保護設定の項目が更新され、
      • config.action_controller.default_protect_from_forgery
      • protect_from_forgery の推奨な使い方 がより明確に説明されています。

  1. 影響範囲・注意点

影響を受けるコード

  • 典型的には次のようなコードを含むアプリ:
ruby
class ApplicationController < ActionController::Base
  protect_from_forgery  # 引数なし
end

このようなアプリは Rails 8.2 にアップデートすると deprecation warning が出ます。

対応方針

  • 必ず戦略を明示するように修正する必要があります。

多くの HTML フォーム主体のアプリであれば:

ruby
protect_from_forgery with: :exception

が妥当です。

API コントローラ等でセッションを使わない場合は:

ruby
protect_from_forgery with: :null_session

を検討します。

default_protect_from_forgery を使っている場合

  • config.action_controller.default_protect_from_forgery = true を設定している場合、
    • ApplicationController などで明示的に protect_from_forgery を呼んでいなければ、そのまま with: :exception が適用され、挙動は変わりません。
    • もし ApplicationController で改めて protect_from_forgery を引数なしで呼んでいると、そこに対して deprecation が出ます。どちらの設定を主軸にするかを決めて、片方に統一するのがよいです。

  1. 参考情報 (あれば)

#56523 CI: Add libvips package to generated ci.yml

マージ日: 2026/1/8 | 作成者: @stevepolitodesign

  1. 概要 (1-2文で)
    Rails アプリ生成時に自動で作られる GitHub Actions 用 ci.yml に、Active Storage を使う場合は画像処理ライブラリ libvips をインストールするステップを追加する変更です。--skip-active-storage を付けた場合は従来どおり libvips は含まれません。

  1. 変更内容の詳細

何が問題だったか

  • Rails 7 以降、Active Storage はデフォルトで image_processing + vips を利用可能ですが
  • Rails new で生成される CI 設定 (.github/workflows/ci.yml 相当) には libvips のインストールが含まれておらず
  • CI 上で Active Storage の画像処理関連テストを実行すると「libvips が無い」ことで失敗する可能性がありました。

今回の変更点

app generator (rails new) のロジック変更

railties/lib/rails/generators/app_base.rb に、CI 設定生成時の条件分岐が追加されています。

イメージとしては以下のようなロジックです(擬似コード):

ruby
# app_base.rb のイメージ
def ci_config
  template "ci.yml.tt", ".github/workflows/ci.yml"
end

# テンプレート側(ci.yml.tt)のイメージ
# (実際には ERB で条件分岐している)
if !options[:skip_active_storage]
  # CI ジョブ内で libvips をインストール
  # 例: apt-get install -y libvips
end

実際には app_base.rb 側で「Active Storage をスキップしているかどうか」の情報をテンプレートに渡し、テンプレート内で libvips インストール行を出し分ける形を取っていると考えられます。

CHANGELOG の更新

railties/CHANGELOG.md に、以下のような趣旨の記述が追加されています:

  • Rails アプリ生成時の CI 設定に libvips を含めるようになった
  • ただし --skip-active-storage を指定した場合は含まれない

  1. 影響範囲・注意点

影響範囲

  • 対象: この PR が入ったバージョン以降で rails new を実行し、GitHub Actions の CI 設定を生成した場合
  • 条件: rails new my_app 実行時に --skip-active-storage を付けない(= Active Storage を使う)と
    • .github/workflows/ci.ymllibvips を OS パッケージとしてインストールするステップが含まれるようになります。
  • すでに存在するアプリの CI には自動では影響せず、新規生成の CI 設定のデフォルトが改善されるだけです。

得られるメリット

  • CI 上で Active Storage + image_processing(vips) を使うテストが、そのまま動作しやすくなります。
  • 開発者が手動で libvips を CI ワークフローに追加する手間が減ります。

注意点

  • 既存アプリの CI 設定は自動更新されないため、すでにあるリポジトリで Active Storage + vips を利用していて CI が失敗している場合は、自分で CI に libvips を追加する必要があります。

    • Ubuntu ランナーの例(GitHub Actions):

      yaml
      jobs:
        test:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - name: Install system dependencies
              run: |
                sudo apt-get update
                sudo apt-get install -y libvips
            # 以降、Ruby セットアップ・bundle・test 実行など
  • --skip-active-storage を指定した場合は、従来どおり libvips 関連の記述は含まれないため、不要なパッケージが CI に入ることはありません。


  1. 参考情報 (あれば)

#56529 Clarify that column default values don't apply to existing records [ci skip]

マージ日: 2026/1/8 | 作成者: @yujiteshima

  1. 概要 (1-2文で)
    Active Record Migrations ガイドの default オプションの説明に、「デフォルト値は新規レコードにのみ適用され、既存レコードは変わらない」ことを明示的に追記したドキュメント修正の PR です。既存のカラム追加や変更時に「既存レコードも自動的にデフォルト値で更新される」と誤解しないようにするのが目的です。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル: guides/source/active_record_migrations.md
  • 変更内容: Active Record Migrations ガイド内の「カラム修飾子 default」に関する説明に、以下の点を明示する一文が追加されました。
    • default で指定した値は「新しく作成されるレコード」に対してのみ適用される
    • すでに存在するレコードは、もともとの値のままであり、NULL のままのカラムも更新されない

PR の背景で挙がっている典型例:

ruby
# 例: 既存の products テーブルにカラムを追加
add_column :products, :inventory_count, :integer, default: 0

このマイグレーションを実行しても、既存レコードの inventory_count は 0 にはならず、NULL のまま です。
0 が入るのは、このマイグレーション適用後に作成される新規 Product レコードだけです。

この仕様をガイドに明示し、以下のような勘違いを防ぐようにしています。

  • 誤解: 「default: 0 を付けたから、既存の行も全部 0 に変わるだろう」
  • 実際: 「既存行は変わらないため nil(DB 的には NULL)のまま残る」

その結果、例えば以下のようなコードで NoMethodError が起きうることに触れています:

ruby
# inventory_count が nil の既存レコードでエラー
product.inventory_count.to_i  # to_i なら問題ないが、nil で呼べないメソッドだとエラー
product.inventory_count.nonzero? # => NoMethodError: undefined method `nonzero?' for nil:NilClass

  1. 影響範囲・注意点
  • 影響範囲:

    • 実装コードではなく ガイド(ドキュメント)のみの変更 のため、Rails の挙動そのものに変更はありません。
    • ただし、今後ガイドを読んだ開発者が、マイグレーション設計時にこの仕様を前提として行動しやすくなります。
  • 注意点 (開発者向け実務上のポイント):

    1. 既存レコードも更新したい場合は、別途 UPDATE が必要

      ruby
      # カラム追加
      add_column :products, :inventory_count, :integer, default: 0
      
      # 既存レコードを 0 に更新したい場合は明示的にやる
      Product.update_all(inventory_count: 0)

      もしくは、マイグレーション内で execute を使って SQL を発行する等。

    2. NOT NULL 制約と組み合わせる際の注意

      • 次のようにすると、既存レコードの inventory_countNULL のままなのに NOT NULL 制約だけ付いてしまい、マイグレーションや後続の処理でエラーになり得ます。
        ruby
        add_column :products, :inventory_count, :integer, default: 0, null: false
      • 安全なパターンの一例:
        ruby
        add_column :products, :inventory_count, :integer, default: 0
        
        # 既存行を 0 で埋める
        Product.update_all(inventory_count: 0)
        
        # その後で null: false 制約を付与
        change_column_null :products, :inventory_count, false
    3. アプリ側での nil ハンドリング

      • デフォルト値に頼りすぎず、アプリケーションコード側でも nil を許容するか、to_i などで防御的に扱うことが有効です。
        ruby
        product.inventory_count.to_i  # nil の場合でも 0 になる

  1. 参考情報 (あれば)
  • 該当 PR: https://github.com/rails/rails/pull/56529
  • 元 issue: https://github.com/rails/rails/issues/56520
    • add_column :products, :inventory_count, :integer, default: 0 で既存レコードも 0 に更新されると期待した」という混乱報告
  • 一般的な知識としても、RDBMS(PostgreSQL, MySQL 等)では「カラム定義の DEFAULT は、その後作られる行のデフォルト」であり、「既存行を一括更新する機能ではない」ことを念頭に置く必要があります。

#56487 Improve authentication generator test template

マージ日: 2026/1/8 | 作成者: @callmesangio

  1. 概要 (1-2文で)
    Rails の認証 generator が生成する sessions_controller_test.rb のテンプレートが微修正され、ファイル名の拡張子を .tt に揃えるとともに、テストコード内の不要な User.take 呼び出しがインスタンス変数に差し替えられました。主にメンテナンス性・一貫性・テストの明瞭さ向上を目的とした小さな改善です。

  1. 変更内容の詳細

変更ファイル:
railties/lib/rails/generators/test_unit/authentication/templates/test/controllers/sessions_controller_test.rb.tt

(1) テンプレートファイル名に .tt 拡張子を付与

  • もともと sessions_controller_test.rb という名前だったテンプレートファイルが、sessions_controller_test.rb.tt に変更されました。
  • Rails の generator テンプレートは .tt (Thor::Actions のテンプレート) 拡張子を付けるのが通例であり、今回それに合わせて命名を統一しています。
  • この変更により generator 内での扱いが明示的になり、「これはそのままコピーされるファイル」ではなく「テンプレートとして加工されるファイル」であることが分かりやすくなります。

(2) テスト内の User.take@user に置き換え
説明文から推測される典型的な変更イメージは次のようなものです(実際のコードは 1 行差分のみですが、趣旨を示すためのサンプルです):

変更前(イメージ):

ruby
setup do
  @user = users(:one)
end

test "should create session" do
  post login_url, params: { email: User.take.email, password: "secret" }
  assert_redirected_to root_url
end

変更後(イメージ):

ruby
setup do
  @user = users(:one)
end

test "should create session" do
  post login_url, params: { email: @user.email, password: "secret" }
  assert_redirected_to root_url
end

改善点:

  • すでに setup@user を用意しているにもかかわらず、User.take で再度 DB からレコードを取得していたため、冗長かつテストの意図が分かりづらかった。
  • @user を使うことで:
    • DB への不要なクエリを避けられる(テスト速度・負荷のわずかな改善)。
    • fixture や setup で明示的に準備されたユーザーを使っていることが明確になる。
    • ランダムなレコード取得 (take) に依存せず、より決定的なテストになる。

  1. 影響範囲・注意点
  • 影響範囲:

    • この PR は「認証 generator が新しく生成するテストファイルのテンプレート」にのみ影響します。
    • 既に生成済みの sessions_controller_test.rb には一切影響しません(手動で更新しない限りはそのまま)。
    • 動作変更レベルではなく、生成されるテストコードの書き方・スタイルが少し改善された類の変更です。
  • 注意点:

    • 自作の generator で .tt を付けていなかった場合、本 PR をきっかけに命名規則を見直すとよいかもしれません(Rails 本体が .tt を推奨している事実上のシグナルと考えられます)。
    • @user を使う形になったことで、テンプレートをカスタマイズする際は setup@user を必ず定義している前提があることに注意してください。@user を削除したり名前変更した場合は、テスト本体の参照も合わせて修正する必要があります。

  1. 参考情報 (あれば)
  • Rails Guides: Generators の仕組み
    https://guides.rubyonrails.org/generators.html
    .tt テンプレートファイルの扱いなど、generator の仕組みが解説されています。

  • Thor::Actions (Rails の generator が内部で利用)
    .tt テンプレート拡張子を使った変数展開の仕組みなどに関係します。


#56427 [ci skip] Fix API docs of AS::Inflector.humanize and String#humanize

マージ日: 2026/1/8 | 作成者: @callmesangio

  1. 概要 (1-2文で)
    ActiveSupport::Inflector.humanizeString#humanize のドキュメントに誤解を招く表現があったため、keep_id_suffix オプションの実際の挙動(末尾 _id を削除しないが、大文字化はしない)に合わせて説明とサンプルが修正された PR です。コードの挙動自体は変わっておらず、ドキュメントのみの更新です。

  1. 変更内容の詳細

対象メソッド

  • ActiveSupport::Inflector.humanize
  • String#humanize (ActiveSupport の拡張)

どちらも「keep_id_suffix: オプション付きで呼び出したときの挙動説明」が修正対象です。

挙動のポイント

keep_id_suffix: true を指定したときの実際の挙動は次の通りです。

ruby
ActiveSupport::Inflector.humanize("author_id", keep_id_suffix: true)
# => "Author id"

"author_id".humanize(keep_id_suffix: true)
# => "Author id"

このオプションは:

  • 末尾の _id を削除しない(= suffix を保持する)
  • ただし _id 部分は 大文字化されない"Author id"id はそのまま)

という挙動になっています。

今回の PR では、この実装にドキュメントを合わせるために、API ドキュメントの説明文とサンプルコード内の期待値が修正されています("Author Id" のような誤った例になっていた、等の可能性が高い)。

変更は以下 2 ファイルのコメント(API ドキュメント)に限定されています。

  • activesupport/lib/active_support/core_ext/string/inflections.rb
  • activesupport/lib/active_support/inflector/methods.rb

差分はそれぞれ 1 行ずつ(+1 / -1)で、メソッドの実装には一切手が入っていません。


  1. 影響範囲・注意点
  • ランタイムの挙動変更は一切なし
    既存アプリケーションで humanize(keep_id_suffix: true) を使用している場合も、動作はこれまで通りです。テストが落ちるような互換性の破壊はありません。

  • ドキュメントを前提にしたテスト・実装への影響
    もし以前のドキュメントの説明に基づいて、

    ruby
    expect("author_id".humanize(keep_id_suffix: true)).to eq("Author Id")

    のようなテスト・実装を書いていた場合、それは「実装とは違う期待値」を持っていることになるため、この PR でドキュメントを見直したタイミングでテスト内容も変更を検討すべきです。

  • keep_id_suffix が行うのは「削除しない」だけ
    keep_id_suffix: true は「id を特別視して人間っぽく整形する」オプションではなく、「_id を削除しない」ことだけを担うオプションである点を、今後のコードリーディングや実装時に意識しておくと混乱が減ります。


  1. 参考情報 (あれば)
  • PR 本体: https://github.com/rails/rails/pull/56427
  • 対象メソッドのドキュメント(edge guides / API ドキュメント)
    • ActiveSupport::Inflector#humanize
    • String#humanize (ActiveSupport core extensions)

ドキュメントを参照する際は、「keep_id_suffix_id を削除しないだけで、id を大文字化したり別表記にしたりはしない」という点を前提に読むとよいです。


#56542 Enable Arel::TreeManagers to use Table's engine

マージ日: 2026/1/8 | 作成者: @hmcguire-shopify

  1. 概要 (1-2文で)
    Arel の TreeManager 系クラス(SelectManager, InsertManager, UpdateManager, DeleteManager)が、初期化時に渡された Arel::Tableengine を自動的に利用して SQL をコンパイルするようになりました。これにより、複数 DB アダプタ利用時でも、明示的にエンジンを渡さなくても適切なアダプタで to_sql が実行されます。

  1. 変更内容の詳細

これまでの問題点

従来の挙動では、TreeManager#to_sql は常に Arel::Table.engine(実質 ActiveRecord::Base)を使って Arel ツリーをコンパイルしていました。

そのため、例えばマルチ DB/マルチアダプタ環境で、あるモデルが ActiveRecord::Base とは別の接続・アダプタを使っている場合、単純に以下のようにすると:

ruby
Arel::InsertManager.new(Model.arel_table).to_sql

SQL コンパイル時に ActiveRecord::Base 側のアダプタが使われてしまい、アダプタ非対応の SQL が出たり、型マッピングが崩れたりといった問題が発生し得ました。
これを回避するには、明示的にエンジンを渡す必要がありました:

ruby
Arel::InsertManager.new(Model.arel_table).to_sql(Model)

今回の変更点

TreeManager がテーブルを保持し、その engine を使うように

Arel::TreeManager の設計が見直され、イニシャライザで渡された Arel::Table を内部状態として保持し、その engineto_sql のデフォルトとして使用するようになりました。

PR 説明の通り、今後は:

ruby
Arel::InsertManager.new(Model.arel_table).to_sql

と書いた場合、自動的に Model のエンジン(= Model.connection が持つアダプタ)が使用されます。
engine が特定できない場合のみ、フォールバックとして ActiveRecord::Base が使われます。

対象クラス

この仕組みは以下の Arel マネージャクラスに適用されています:

  • Arel::SelectManager
  • Arel::InsertManager
  • Arel::UpdateManager
  • Arel::DeleteManager

各クラスで TreeManager の変更に追随する形で、テーブルを渡して初期化し、そのテーブル由来のエンジンが活用されます。

代表的な利用例

Before (旧挙動 / マルチアダプタ環境で安全に使うための書き方):

ruby
manager = Arel::InsertManager.new(Model.arel_table)
sql = manager.to_sql(Model)  # Model を明示しないと ActiveRecord::Base のエンジンが使われる

After (新挙動):

ruby
manager = Arel::InsertManager.new(Model.arel_table)
sql = manager.to_sql          # 渡した arel_table の engine (Model) が自動的に使われる

SelectManager, UpdateManager, DeleteManager も同様の挙動になります。

テスト追加

以下のテストが追加され、挙動が検証されています:

  • activerecord/test/cases/arel/support/tree_manager_behavior.rb
    • TreeManager 共通のふるまいとして、「テーブルのエンジンをデフォルトで使用する」ことをテスト。
  • insert_manager_test.rb, update_manager_test.rb, delete_manager_test.rb
    • 各マネージャで、to_sql 呼び出し時にテーブル由来のエンジンが使われることを確認。

TableTreeManager 本体にも必要最小限の変更が入り、エンジンの解決ロジックが修正されています。


  1. 影響範囲・注意点
  • マルチ DB / マルチアダプタ環境での利便性向上

    • これまで to_sql に毎回明示的にモデル(あるいはエンジン)を渡していた箇所は、その指定を省略できる可能性があります。
    • 特に、複数アダプタ(例: PostgreSQL + MySQL)の混在環境で、誤ったアダプタで SQL が組み立てられるリスクが減ります。
  • 既存コードとの互換性

    • 既存コードで to_sql(SomeEngine) と明示的にエンジンを渡している場合、その挙動は変わりません。
    • デフォルトのエンジンが変わるのは「これまで暗黙に ActiveRecord::Base が使われていたケース」であり、今後は「関連する Arel::Table のエンジン」が優先されます。
    • もし意図的に ActiveRecord::Base のエンジンでコンパイルしていたコードがあれば、今後もその挙動を維持したい場合は引き続き to_sql(ActiveRecord::Base) のように明示してください。
  • 独自に Arel を利用している場合の確認ポイント

    • 生 Arel を多用しているアプリケーション・ライブラリでは、TreeManager やそのサブクラスを直接初期化している箇所を確認し、「どの Arel::Table を渡しているか」「そのテーブルの engine は何になっているか」を見直すと安全です。
    • テーブルに適切な engine が設定されていることが前提となるため、カスタムテーブルや特殊な接続まわりを扱っている場合は、Arel::Table.new(..., engine: custom_engine) のような指定が正しく行われているかをチェックするとよいです。

  1. 参考情報 (あれば)
  • 該当 PR: Enable Arel::TreeManagers to use Table's engine (#56542)
  • 関連クラス:
    • Arel::TreeManager
    • Arel::SelectManager
    • Arel::InsertManager
    • Arel::UpdateManager
    • Arel::DeleteManager
    • Arel::Table
  • 想定ユースケース:
    • Rails のマルチ DB 機能 (connects_to など) や、異なるアダプタを使う複数のモデルを同一アプリケーション内で扱う場合。
    • Arel を直接使ってカスタムクエリを組み立てるライブラリ・Gem。

#56556 Fix postgresql/schema_dumper relation_name appending the wrong schema…

マージ日: 2026/1/8 | 作成者: @chiperific

  1. 概要 (1-2文で)
    PostgreSQL 用の schema_dumper が、テーブルの schema を誤って付与してしまう不具合を修正した PRです。複数スキーマ環境で schema.rb をダンプする際、正しいスキーマ名でリレーションを表現できるようになります。

  1. 変更内容の詳細

※PR本文からは細かいコード断片は示されていませんが、ファイル構成と関連 Issue (#56555) から、以下のような修正であると読み取れます。

問題の背景

  • Rails の PostgreSQL アダプタは、rake db:schema:dump などで schema.rb を生成する際に ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaDumper を使います。
  • このとき、テーブル/インデックス/外部キーなどの「リレーション名」にスキーマ名を付与する処理がありました。
  • マルチスキーマ環境(例: public.users, tenant1.users など同名テーブルが複数スキーマに存在)で、このスキーマ名の付け方が誤っており、
    • 別スキーマの名前を付けてしまう
    • あるいは、現在のスキーマコンテキストとずれた名前になってしまう
      といった「誤ったスキーマ名付きリレーション」が schema.rb に出力されるバグがありました。

この PR の修正内容

主な変更点は以下です。

  1. postgresql/schema_dumper.rb のスキーマ名付与ロジックの修正

    • リレーション名 (relation_name) にスキーマ名を付けるとき、
      • そのリレーションが属しているスキーマを正しく参照するよう修正
      • 「現在の検索パス」や「別オブジェクトのスキーマ」を誤って流用していた処理を正した
    • 結果として、schema.rb 内では
      • create_table "schema_name.table_name" のように書かれるべきところが
      • 別の schema_name になってしまう問題が解消されます。
  2. テストの追加 (activerecord/test/cases/adapters/postgresql/schema_test.rb)

    • 複数スキーマ・同名テーブルが存在する状況を再現するテストが追加されています。
    • 想定されるテストイメージ:
      • CREATE SCHEMA a; CREATE SCHEMA b;
      • a.usersb.users の両方を作成
      • schema.rb をダンプ
      • それぞれに対応した create_table "a.users" / create_table "b.users" が正しく出力されるかを検証
    • これにより、今後同種の回 regress を防止します。
  3. CHANGELOG の更新 (activerecord/CHANGELOG.md)

    • Active Record の CHANGELOG に、このバグ修正が記載されました。
    • 挙動変更として扱われる程度の修正であることがわかります。

  1. 影響範囲・注意点
  • 影響を受けるケース

    • DB が PostgreSQL
    • 複数スキーマを使用している(search_path 変更や schema_search_path を活用している)
    • 同名テーブル/インデックス/外部キーなどが別スキーマに存在する
    • db:schema:dump を使って schema.rb を生成している
  • 期待できる改善

    • これまで schema.rb に誤ったスキーマ付きリレーションが出ていた場合、
      • db:schema:load が失敗する
      • 別スキーマにテーブルを作ってしまう といった問題が解消される可能性が高いです。
    • 既存の schema.rb を修正する必要がある場合は、この修正を含む Rails バージョンに上げた後、一度 db:schema:dump を取り直すのが安全です。
  • 後方互換性

    • 「正しくなかったものが正しくなる」タイプのバグ修正のため、標準的な単一スキーマ構成では基本的に影響はありません。
    • もし、誤った挙動を前提にカスタムスクリプトや CI を組んでいた場合(稀だと思われます)は、schema.rb の出力差分が発生する可能性があります。

  1. 参考情報 (あれば)
  • 該当 Issue: https://github.com/rails/rails/issues/56555
    • どのような状況で誤ったスキーマ名が付くのか、再現手順やエラーメッセージなどの詳細が記載されているはずです。
  • 関連コード:
    • ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaDumper
    • db/schema.rb 生成ロジック(ActiveRecord::SchemaDumper.dump

#56551 Improve uniqueness validation query building by adding case-sensitive operators to Arel

マージ日: 2026/1/8 | 作成者: @Saidbek

  1. 概要 (1-2文で) Rails の一意性バリデーションがクエリ AST を組み立てる段階で DB コネクションを取得してしまう問題を解消するため、Arel に「大文字小文字を区別/非区別する比較演算ノード」が追加されました。これにより、ユニークネスバリデーションのクエリ生成が、DB 接続に依存せずに行えるようになります。

  1. 変更内容の詳細

背景

  • ActiveRecord の validates :xxx, uniqueness: true は、DB 上の既存レコードと重複していないかを確認するためにクエリを組み立てます。
  • 大文字小文字の扱い(case_sensitive: true/false)によって、DB 方言ごとに異なる SQL(LOWER() を使う、COLLATE を使う、など)を生成する必要があり、そのロジックの一部が「クエリ組み立て時点で接続情報(アダプタ)を参照する」実装になっていました。
  • その結果、クエリ AST(Arel)を作るだけの段階で DB コネクションが checkout されてしまうという TODO が残っており、それを解消するのが今回の PR です。
  • #51353 で大部分は解消されていたが、残っていたユニークネスバリデーションまわりの接続取得を取り除くフォローアップです。

追加された Arel ノードとメソッド

1) Arel::Nodes::CaseSensitiveEquality / CaseInsensitiveEquality

activerecord/lib/arel/nodes/equality.rb に、以下の 2 種類の Arel ノードが追加されています:

  • CaseSensitiveEquality
  • CaseInsensitiveEquality

これらは、既存の Arel::Nodes::Equality=)と同様に、左辺・右辺を持つ二項演算子ノードですが、「大文字小文字の扱い」を意味論として持つ専用ノードになっています。

2) Arel::Predications に新しい述語メソッド

activerecord/lib/arel/predications.rb に、以下のメソッドが追加されています:

  • #case_sensitive_eq
  • #case_insensitive_eq

イメージとしては、以下のように使えるようになります(実際の Rails 内部コードの簡略イメージ):

ruby
users = Arel::Table.new(:users)

# 大文字小文字を区別した比較
pred1 = users[:email].case_sensitive_eq("foo@example.com")
# => Arel::Nodes::CaseSensitiveEquality の AST が構築される

# 大文字小文字を区別しない比較
pred2 = users[:email].case_insensitive_eq("foo@example.com")
# => Arel::Nodes::CaseInsensitiveEquality の AST が構築される

この時点では「どのような SQL 文字列になるか」は決まっておらず、単に AST 上で「ケースセンシティブか/インセンシティブか」を情報として持つだけです。

3) Arel::Visitors::ToSql に対応

activerecord/lib/arel/visitors/to_sql.rb に、これら新ノードを SQL に変換するロジックが追加されています。

  • 各 DB アダプタは Arel::Visitors::ToSql を拡張/オーバーライドしており、
    • MySQL / PostgreSQL / SQLite / 他 DB で「ケースセンシティブ/インセンシティブな比較」をどう表現するかは、Visitor 側で決定されます。
  • つまり、「AST の構築(case_sensitive_eq / case_insensitive_eq の呼び出し)」と「SQL 文字列への変換(アダプタ依存)」がきれいに分離されます。

4) ActiveRecord::Validations::Uniqueness の修正

activerecord/lib/active_record/validations/uniqueness.rb のロジックが、既存の DB 接続依存のクエリ構築から、新しい Arel ノードを使った実装に変更されています(+8/-13)。

以前は例えば、

  • アダプタクラスやコネクションの情報に基づいて、
  • case-sensitive / insensitive の SQL を Ruby コード側で直接決めていた

ようなコードがあり、そのため「どの SQL を吐くか」を決めるタイミングで DB コネクション(アダプタ情報)に触れる必要がありました。

PR 後は、

  • uniqueness バリデーション内で、
    • column = arel_table[:email] などとして Arel 属性を取り出し、
    • column.case_sensitive_eq(value) または
    • column.case_insensitive_eq(value)
  • という形で AST だけを構築 するようになります。
  • どのように SQL へ落とし込むかは、ToSql Visitor(アダプタごとの実装)が後段で判断します。

これにより、

  • 「どの DB か」「どのコレーションか」といった接続依存情報は、実際に SQL を発行する直前のフェーズにだけ必要になり、
  • AST 構築(バリデーションのクエリビルド)時には DB コネクションを checkout する必要がなくなります。

  1. 影響範囲・注意点

影響範囲

  • 直接的には、validates :column, uniqueness: { case_sensitive: true/false } を利用する全アプリに関係します。
    • ただし外部 API は変わっておらず、アプリケーションコード側の変更は不要です。
  • 内部的には、以下に影響が出ます:
    • Arel を直接使っている場合で、CaseSensitiveEquality / CaseInsensitiveEquality を利用したいライブラリ・コード
    • Arel::Visitors::ToSql を独自拡張しているアダプタ/Gem
  • 以前、ユニークネスバリデーションのクエリビルド時に「なぜか DB コネクションチェックアウトが走っていた」ケースでは、
    • その checkout が発生しなくなり、接続プールの圧迫・並列性への悪影響が減ります。

注意点

  • Arel の Visitor を自作・拡張している場合:
    • CaseSensitiveEquality / CaseInsensitiveEquality に対する visit_Xxx 実装を持っていないと、期待通りの SQL が出ない可能性があります。
    • Rails の標準アダプタについてはこの PR で対応済みですが、独自アダプタや古い fork を使っている場合は要確認です。
  • DB ごとの動作差:
    • 「ケースインセンシティブな比較」がどう表現されるか(LOWER(column) = LOWER(value)COLLATE / ILIKE など)はアダプタに委ねられています。
    • 以前からそうですが、「コレーション」や「インデックスの種別」との組み合わせによって実際の動作が変わる点は引き続き意識が必要です(この PR はそこを変えるものではありません)。

  1. 参考情報 (あれば)
  • 関連 PR: #51353 — 「クエリビルド時のコネクション checkout の削減」を行った前段の PR。
  • 影響を受ける内部 API:
    • ActiveRecord::Validations::Uniqueness
    • Arel::Nodes::CaseSensitiveEquality
    • Arel::Nodes::CaseInsensitiveEquality
    • Arel::Predications#case_sensitive_eq
    • Arel::Predications#case_insensitive_eq
    • Arel::Visitors::ToSql の新ノード対応

この PR の主眼は「Arel AST の表現力を増やし、DB 依存の判断を Visitor に閉じ込めることで、バリデーション時の DB 接続依存を排除する」点にあります。アプリケーションコードの互換性は保たれつつ、内部の設計がよりクリーンになっています。


#56541 Remove system tests from default CI template

マージ日: 2026/1/8 | 作成者: @eileencodes

  1. 概要 (1–2文で)
    Rails の新規アプリ生成時に使われるデフォルトの CI 設定テンプレートから、システムテストを実行する設定がデフォルトでは外され、コメントアウトされたブロックとして扱われるようになりました。これは、別 PR (#56272) によりシステムテストが標準生成されなくなった変更と整合を取るための対応です。

  1. 変更内容の詳細

対象ファイル:

  • railties/lib/rails/generators/rails/app/templates/config/ci.rb.tt

このファイルは rails new で新規アプリを作るときに生成される config/ci.rb のテンプレートで、Rails が公式に用意する CI 実行内容の「サンプル定義」のような位置付けです。

今回の変更点は以下の通りです。

  • 以前は システムテスト (system tests) を CI で実行する設定が、他のテスト同様に「有効な状態」で含まれていました。
  • PR #56272 によって、Rails アプリ生成時にシステムテスト関連ファイルがデフォルトでは生成されなくなったため、
    • CI テンプレート側でも、システムテストを「標準で回す前提」をやめ、
    • 「コメントアウトされたサンプル」として残す形に変更されています。

擬似コードレベルのイメージ:

ruby
# 変更前 (イメージ)
Rails.application.configure do
  # ...
  config.ci.tasks = [
    "test:models",
    "test:controllers",
    "test:system" # システムテストもそのまま有効
  ]
end

# 変更後 (イメージ)
Rails.application.configure do
  # ...
  config.ci.tasks = [
    "test:models",
    "test:controllers",
    # システムテストを使いたい場合はコメントを外して有効化する:
    # "test:system"
  ]
end

実際の差分は +5/-5 行程度で、test:system(もしくはそれに相当するシステムテスト向け CI 設定)がコメントアウトされる、あるいは「コメントアウトされたセクション」に移動される形になっています。


  1. 影響範囲・注意点
  • 新規に rails new で作成されるアプリのみが対象で、既存アプリの CI 設定 (config/ci.rb など) は自動変更されません。
  • 新規アプリでは、Rails が生成するデフォルトの CI 設定において:
    • システムテストがデフォルトでは実行されなくなります。
    • システムテストを使いたい場合は、手動でコメントを外して CI 対象に含める必要があります。
  • これにより:
    • システムテスト関連ファイルが存在しない状態で test:system を実行して CI が落ちる、といった「初期状態でのノイズ」が減ります。
    • 逆に、システムテストを使うつもりのチームは、config/ci.rb をきちんと確認・編集することが前提になります。

運用上の注意:

  • システムテストを導入する場合の典型的な手順:
    1. system test のファイル・ディレクトリを生成する(必要に応じて generator を利用)。
    2. config/ci.rb を開き、コメントアウトされている system test 用の設定行(例: "test:system")を有効化。
    3. CI 上で bin/rails test:system または相当のタスクが実行されることを確認。

  1. 参考情報 (あれば)
  • この PR が依存している/整合を取っている PR:
    • PR #56272: 「システムテストや関連ファイルをデフォルト生成しない」変更を導入
  • この PRがクローズしている Issue:
    • Issue #56539: デフォルト CI テンプレートが、もはやデフォルト生成されないシステムテストを実行しようとしてしまう問題報告

この一連の変更により、「Rails デフォルトのプロジェクト構成」と「Rails がサンプルとして提供する CI 設定内容」が一致するようになっています。


#56548 refactor(test): consolidate test helper configuration into support module

マージ日: 2026/1/7 | 作成者: @seuros

  1. 概要 (1-2文で)
    このPRは、Active Record のテスト用ヘルパ設定を専用のサポートモジュール群に整理・集約し、QUOTED_TYPE などの定数や設定をグローバルではなく ARTest 名前空間配下に移動したリファクタリングです。テスト構成の分離と見通しを良くしつつ、既存テストの挙動は維持することを目的としています。

  1. 変更内容の詳細

a. テストヘルパ設定のモジュール化・分割

これまで activerecord/test/cases/helper.rb に散在していた各種設定・ヘルパが、新しいサポートファイルに分割されました。

新規追加されたファイル:

  • activerecord/test/support/adapter_config.rb
  • activerecord/test/support/encryption_config.rb
  • activerecord/test/support/global_config.rb
  • activerecord/test/support/postgresql_config.rb

これらは概ね次のような責務を持つと考えられます:

  • adapter_config.rb
    • 使用する DB アダプタごとの共通設定(接続設定、アダプタ固有のフラグなど)を ARTest 名前空間にまとめる。
  • encryption_config.rb
    • Active Record の暗号化関連テストに必要な設定(鍵、暗号化機能のオン/オフ、テスト用のデフォルト設定)を扱う。
  • global_config.rb
    • テスト全体に影響するグローバルな Active Record 設定(default_timezone, error_on_ignored_order, など)を一元化。
  • postgresql_config.rb
    • PostgreSQL 用に特化した追加設定(拡張機能、型マッピング、コネクションパラメータなど)を切り出し。

これによって、helper.rb の行数が -48 行 と大きく減り、テスト設定の関心ごとがファイル単位で明確に分離されました。

b. QUOTED_TYPE 定数を root レベルから ARTest に移動

PR 説明にある通り、QUOTED_TYPE 定数が「ルートレベル(トップレベル定数)」に置かれていた TODO を解消し、ARTest 名前空間配下に移動しています。

イメージとしては、以下のような変更です:

ruby
# 変更前 (例)
QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name("type")

# 変更後 (例)
module ARTest
  QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name("type")
end

これに伴い、各テストファイルでの参照も変更されています:

  • activerecord/test/cases/associations/eager_test.rb
  • activerecord/test/cases/associations/has_many_associations_test.rb
  • activerecord/test/cases/associations/join_model_test.rb
  • activerecord/test/cases/base_test.rb
  • activerecord/test/cases/calculations_test.rb
  • activerecord/test/cases/finder_test.rb
  • activerecord/test/cases/inheritance_test.rb
  • activerecord/test/models/comment.rb

などで、QUOTED_TYPE を直接参照していた箇所が ARTest::QUOTED_TYPE のように名前空間付き参照へと修正されています(+ / - の行数が少ないのは、このような参照の書き換えによるものと考えられます)。

c. test_case.rb 側でのサポートモジュール読み込み

activerecord/test/cases/test_case.rb で +1 行の変更が入っており、ここから新たなサポートモジュール(support/global_config など)を require している可能性が高いです。

標準的には次のようなパターンです:

ruby
# 例
require "support/global_config"
require "support/adapter_config"
require "support/encryption_config"
require "support/postgresql_config"

これにより、すべての Active Record テストケースがこれらの設定を共有できるようになります。


  1. 影響範囲・注意点
  • 影響は基本的にテストコードのみ
    変更ファイルは activerecord/test/** 以下に限定されており、ライブラリ本体 (lib/active_record/...) や API 挙動には影響しません。

  • テスト内の定数参照の変更

    • 今後新たにテストを書く際に、QUOTED_TYPE を使う場合はトップレベルではなく ARTest::QUOTED_TYPE(または ARTest 経由で提供される他の設定)を参照する必要があります。
    • 既存の社内パッチや独自テストでトップレベル QUOTED_TYPE を期待している場合はビルドが壊れる可能性があるため、ARTest::QUOTED_TYPE へ修正する必要があります。
  • テスト設定の拡張ポイントが明確になった

    • DB アダプタや暗号化、PostgreSQL 固有の挙動に対するテスト設定を追加・変更したい場合は、それぞれの support/*_config.rb を編集すればよくなり、helper.rb に設定が肥大化していく問題を回避できます。
  • ネームスペース汚染の軽減

    • テスト環境でトップレベルに定数を定義してしまうことで、本体コードや他テストとの衝突を起こすリスクが減少しています。
    • 今回の QUOTED_TYPE 移動はその一例で、以後も同様のリファクタリングが進む可能性があります。

  1. 参考情報 (あれば)
  • PR: https://github.com/rails/rails/pull/56548
  • ARTest モジュールは Rails の Active Record テストインフラのための名前空間で、DB 接続や環境設定などテスト専用の機能を集約する目的で利用されています。
  • 類似のリファクタリングとして、過去にも activerecord/test/support/ 以下に接続管理や schema 定義、migration 用ヘルパが順次分割されてきており、その流れを継ぐ変更です。

#56547 Fix class variable initialization for type mapping callbacks

マージ日: 2026/1/7 | 作成者: @seuros

  1. 概要 (1-2文で)
    PostgreSQL アダプタの「型マッピング用コールバック」を保持するクラス変数の初期化方法を修正し、前回のPRでテストを個別実行した際に失敗していた問題を解消する変更です。クラス変数の初期化タイミング/方法が原因で、環境によって状態が不安定になるのを防ぐ目的の修正です。

  1. 変更内容の詳細

※PR本文と統計情報から分かる範囲での推測を含みますが、Rails の既存コードスタイルと前後の文脈から、ほぼこのような意図の変更と考えられます。

  • 対象: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter 内の「型マッピング callbacks」を格納するクラス変数

  • 問題:

    • 直前のPRでこのクラス変数の導入/初期化方法が変更された結果、
      • テストを「すべてまとめて」実行すると通るが
      • テストを「個別に」実行すると失敗する
        という状態になっていた、と作者が明言しています。
    • 典型的には次のような状況が考えられます:
      • クラス変数が「他のテストで副作用的に初期化される」ことを前提にしてしまっている
      • @@some_callbacksnil のまま使われるケースが出る
      • 再読み込みや再定義でクラス変数の状態が壊れる
  • 今回の修正内容(推定される方向性):

    • クラス変数の初期化をより堅牢にするために、以下のようないずれか/組み合わせが行われていると考えられます:

      • @@type_mapping_callbacks ||= {} のように「使用時に必ずデフォルト値が入る」パターンに修正
      • class << self; attr_accessor :type_mapping_callbacks; end + クラスインスタンス変数 @type_mapping_callbacks に変更
      • または、class_attribute を使う形に変更
    • 差分が「+3/-2」と非常に小さいことから、実際には次のような1行レベルの修正である可能性が高いです(イメージコード):

      ruby
      # 例: 以前のコード(テストが isolation で壊れる形)
      @@type_mapping_callbacks = {}
      
      # 例: 修正後のコード(遅延初期化)
      @@type_mapping_callbacks ||= {}

      または:

      ruby
      # クラス変数からクラスインスタンス変数への移行例
      class << self
        def type_mapping_callbacks
          @type_mapping_callbacks ||= {}
        end
      end
    • PRコメントで the previous PR broke the tests in isolation とあるため、 「テスト環境の実行順や単体実行に依存しない状態初期化」に変えた、というのが主眼です。


  1. 影響範囲・注意点
  • 影響範囲

    • ActiveRecord の PostgreSQL アダプタにおける「型マッピングの拡張/フック機構」を利用しているコードが、より安定して動作するようになります。
    • 特に、Rails のロード順やテストの実行順に依存していた微妙なバグが出にくくなります。
  • 互換性

    • 振る舞いとしては本来意図していた「常にハッシュ(など)として初期化された callbacks コンテナが存在する」状態に近づける修正なので、正常なコードに対しては後方互換的です。
    • もしアプリ側で PostgreSQLAdapter のクラス変数/クラスインスタンス変数に直接アクセスしていた場合(非推奨なやり方)には、内部実装が微妙に変わっている可能性があるため注意が必要です。
  • テスト・デバッグ面

    • Rails 本体のテストを「個別ファイル」「単一テストケース」で走らせても、type mapping に関する NoMethodError / nil 参照などが起きにくくなります。
    • もし既に type mapping callbacks 周辺で flakiness(ときどき落ちるテスト)があった場合は、この修正で安定する可能性があります。

  1. 参考情報 (あれば)
  • PR: https://github.com/rails/rails/pull/56547
  • 類似のパターンとして、Rails ではクラス変数よりもクラスインスタンス変数や class_attribute が推奨されることが多く、
    「test in isolation で壊れる」問題は、クラス変数の初期化や再読み込み時の扱いが原因になることがよくあります。

#56496 Add PostgreSQLAdapter.register_type_mapping

マージ日: 2026/1/7 | 作成者: @seuros

  1. 概要 (1-2文で)
    PostgreSQLAdapter に、外部 gem が独自の PostgreSQL 型を「正規のインターフェイス」で登録できる register_type_mapping メソッドが追加されました。これにより、postgis や vector などの gem がアダプタを monkey patch せずに型マッピングを拡張できるようになります。

  1. 変更内容の詳細

追加されたインターフェイス

ActiveRecord::ConnectionAdapters::PostgreSQLAdapter に新たに以下のようなメソッドが追加されています(概念的なイメージ):

ruby
# PostgreSQLAdapter 内 (イメージ)
def self.register_type_mapping(oid: nil, name: nil, **options, &block)
  # ここで type map への登録を行う
end

実際の実装では、PostgreSQL の type map(OID ベースの型解決テーブル)に対して、

  • 型名 / OID と
  • それに対応する ActiveRecord の型キャストロジック(OID::Type オブジェクトなど)

を紐付けるためのフックが提供されています。

想定ユースケース

従来、以下のような gem は PostgreSQLAdapter を直接 monkey patch して独自型をねじ込んでいました:

今後は、これらの gem は次のような形で利用できます(擬似コード例):

ruby
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.register_type_mapping(
  name: "geometry"
) do |oid, name, **_|
  # ここで独自の型クラスを返す
  MyPostgis::GeometryType.new(oid, name)
end

ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.register_type_mapping(
  name: "vector"
) do |oid, name, **_|
  MyVector::VectorType.new(oid, name)
end

または、OID ベースで登録する API も用意されている可能性があります(テストファイル名より推測)。
テスト (type_map_registration_test.rb) では、登録した型マッピングが実際に PostgreSQL の type map に反映され、
該当カラムへアクセスした際に期待した型変換が行われることが検証されています。

CHANGELOG

activerecord/CHANGELOG.md にもエントリが追加されており、

  • PostgreSQL 用の新しい型マップ登録 API
    が公式にサポートされたことが明記されています。

  1. 影響範囲・注意点
  • 影響範囲

    • PostgreSQLAdapter を利用しているアプリケーション全体が潜在的な対象ですが、
      既存アプリはこのメソッドを呼ばない限り挙動は変わりません。
    • PostgreSQL の拡張型を扱う gem(PostGIS、vector など)の実装が今後この API に移行していくことで、 ActiveRecord との統合がより安定・保守しやすくなります。
  • 既存コードへの影響

    • 既に monkey patch に頼っている gem / アプリは、即座に壊れることはありませんが、
      今後は register_type_mapping を使う形に移行することで、Rails 本体の内部実装変更に強くなります。
    • Rails 本体側の type map 初期化ロジックとの競合を避けやすくなるため、
      将来的な Rails バージョンアップ時の互換性問題が減ることが期待できます。
  • 注意点

    • 実際に利用する際は、どのキーで登録するか(OID なのか型名なのか)、
      およびブロックに渡される引数(oid, name, limit など)の仕様をソース / ドキュメントで確認しておく必要があります。
    • 同じ型名 / OID に対して複数の gem が登録しようとした場合の挙動(上書きか、エラーか)は
      実装に依存するため、複数の拡張を併用する場合は要確認です。

  1. 参考情報 (あれば)

#56012 Memoize IAM client and set authorization to ADC for GCS Active Storage service

マージ日: 2026/1/7 | 作成者: @jmalcic

  1. 概要 (1-2文で)
    Google Cloud Storage 用 Active Storage サービスにおいて、iam: true 指定時の署名付きURL生成が #55353 により壊れていた問題を、IAM クライアントの認証を元の「ADC (Application Default Credentials) を使う」挙動に戻しつつ、IAM クライアントをメモ化して過剰な ADC 呼び出しを避ける形で修正した PR です。
    あわせて、この挙動を検証するテストと CHANGELOG が追加されています。

  1. 変更内容の詳細

背景 / 何が問題だったか

  • #55353 で GCS の IAM 署名付きURL周りの認証の扱いが変更された結果、
    • デフォルトの ADC(GOOGLE_APPLICATION_CREDENTIALS など)を使っているアプリで
    • Active Storage の GCS サービスに iam: true を指定している場合
    • 署名付き URL 生成時に Google::Apis::AuthorizationError: Unauthorized が発生するようになった。
  • 元 PR は「Google のライブラリ側が適切な scope 付きで自動的に認証を行うはず」という前提で変更していたが、現実にはそうなっておらず、ADC を明示的に利用する必要があった。

この PR での方針

  1. iam: true の場合は、従来どおり ADC を使う挙動を復元

    • Active Storage の GCS サービスで IAM 署名を行う際、
      • デフォルトでは Application Default Credentials を使って IAM クライアントを初期化する。
    • これにより、GOOGLE_APPLICATION_CREDENTIALS にサービスアカウントキーを指定している環境など、従来動いていた構成が再び動くようになる。
  2. IAM クライアントをメモ化(memoize)して、ADC 呼び出し回数を削減

    • 以前のコードでは、iam: true の場合に IAM クライアントの作成・認証取得が複数回行われ、ADC 呼び出しが過剰になる懸念があった。
    • この PR では、GCS サービスインスタンス内で IAM クライアントを 1 度だけ生成して再利用するようにしている。
      • クライアント自体がトークンの有効期限切れを検知してリフレッシュを行うので、メモ化しても認証の有効期限管理は問題ない。

    (擬似的なイメージ)

    ruby
    def iam_client
      @iam_client ||= begin
        client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new
        # デフォルトでは ADC を用いる
        client.authorization ||= Google::Auth.get_application_default(...)
        client
      end
    end

    ※実際のコードでは Google::Auth.get_application_default のような呼び出しや scope の指定が行われ、ActiveStorage 内の責務に合うように書かれています。

  3. 認証手段のオーバーライドは引き続き可能

    今回の修正は「デフォルトを ADC に戻す」だけで、以下の上書き手段は引き続き機能します。

    • #55353 で提案されていたように、
      ruby
      Google::Apis::RequestOptions.default.authorization = my_authorizer
      のように グローバルに Google::Apis の認証を設定する。
    • あるいは、IAM クライアント個別に authorization をセットする。

    つまり、デフォルトは ADC だが、利用側が明示的に別の認証戦略を指定することもできる、という構成です。

  4. テストの追加・修正

    • activestorage/test/service/gcs_service_test.rb に、
      • GOOGLE_APPLICATION_CREDENTIALS がサービスアカウントキーを指しているようなローカル環境でも
      • iam: true 指定の GCS サービスが正常に署名付き URL を生成できること を検証するテストが追加されています。
    • activestorage/test/test_helper.rb にも、GCS テスト用の認証周りをセットアップするためのコードが追加・調整されています。
  5. CHANGELOG の更新

    • activestorage/CHANGELOG.md に今回の挙動変更(バグフィックス)が追記され、
      • GCS の IAM 署名付き URL で ADC が再び使われること
      • 認証がメモ化されること などが記録されています。

  1. 影響範囲・注意点
  • 影響を受けるのは、主に次のケース

    • Active Storage の GCS サービスを使用し、
    • iam: true で IAM ベースの署名付き URL を利用しており、
    • 認証を Application Default Credentials(GOOGLE_APPLICATION_CREDENTIALS など)に頼っているアプリケーション。
  • 期待される変化

    • #55353 適用後に発生していた Google::Apis::AuthorizationError: Unauthorized が解消され、 以前のバージョンと同様に署名付き URL が利用できるようになる。
    • IAM クライアントがメモ化されたことにより、ADC への問い合わせ回数が減少し、パフォーマンスや外部呼び出し回数の面で多少の改善が見込める。
  • 既にカスタム認証を設定している場合

    • Google::Apis::RequestOptions.default.authorization を設定している、または独自に IAM クライアントの authorization を設定しているプロジェクトは、その設定が引き続き優先されます。
    • この PR によるデフォルト挙動の復元は、そうした明示的な設定を壊さないよう設計されています。
  • アップグレード時の確認ポイント

    • GCS + iam: true を使っている場合は、テスト環境で署名付き URL の生成・アクセスが成功するかを確認する。
    • もしグローバルな Google::Apis::RequestOptions.default.authorization を使っている場合、今回の変更で挙動が変わっていないかを軽く確認しておくと安心です(基本的には変わらない想定)。

  1. 参考情報 (あれば)
  • 影響元となった PR: #55353
  • この PR で言及されている失敗テスト:
    • activestorage/test/service/gcs_service_test.rb の IAM 署名付き URL 関連テスト
      GOOGLE_APPLICATION_CREDENTIALS をサービスアカウントキーに設定したローカル環境で Google::Apis::AuthorizationError が出ていたケースに対応)

#56534 Fix SQLite3 schema dump for non-autoincrement integer primary keys

マージ日: 2026/1/7 | 作成者: @khasinski

  1. 概要 (1-2文で)
    SQLite3 を使って id: :integer, default: nil な主キーを持つテーブルを作成した場合に、schema.rb へのダンプ・復元時に誤って AUTOINCREMENT 付きの主キーに変わってしまう不具合を修正した PR です。sqlite_master を参照して実際に AUTOINCREMENT が付与されているかどうかを判定し、スキーマダンプ時に id: :integer, default: nil を正しく出力するようになりました。

  1. 変更内容の詳細

何が問題だったか

元の挙動:

ruby
# migration
create_table :payments, id: :integer, default: nil

SQLite 上ではこの指定により、以下のようなテーブルが作られます:

sql
CREATE TABLE "payments" ("id" integer NOT NULL PRIMARY KEY);
-- AUTOINCREMENT は付かない

しかし schema.rb にダンプすると:

ruby
# BEFORE 修正前
create_table "payments", force: :cascade do |t|
end

id オプションが省略された形で出力されるため、これを別環境で rails db:schema:load すると:

sql
CREATE TABLE "payments" (
  "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL
);

のように、SQLite の「デフォルト挙動」により AUTOINCREMENT が付与されたテーブルとして再作成されてしまい、元テーブルの性質(非 AUTOINCREMENT)が失われていました。

どう直したか

PR では、SQLite の schema dumper (activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb) を修正しています。

主なポイント:

  • sqlite_master テーブルをクエリし、そのテーブル定義の SQL 文を取得。

  • そこに AUTOINCREMENT が含まれているかをチェックすることで、

    • AUTOINCREMENT 付きの整数主キーなのか
    • 単なる integer primary key(AUTOINCREMENT なし)なのか を判定。
  • AUTOINCREMENT が 付いていない 整数主キーに対しては、schema.rb で:

    ruby
    create_table "payments", id: :integer, default: nil, force: :cascade do |t|
    end

    のように id: :integer, default: nil を明示的に出力するように変更。

これにより、schema.rb 経由でテーブルを再生成しても、元の挙動(非 AUTOINCREMENT の整数主キー)が保持されます。

テスト・その他

  • 変更ファイル:
    • sqlite3/schema_dumper.rb: ロジック追加 (+14/-2)
    • primary_keys_test.rb: 期待挙動に合わせて微修正 (-1)
  • バグ修正用のテストが追加 or 更新されており、挙動が回帰テストで担保されています。
  • Active Record の CHANGELOG も更新されており、アプリケーション側から見える動作変更として扱われています。

  1. 影響範囲・注意点
  • 対象:
    • DB: SQLite3
    • パターン: create_table ... id: :integer, default: nil で整数主キーを定義しているテーブル
  • 影響:
    • 今後、この PR を含む Rails バージョンに上げると、db/schema.rbこれまで出ていなかった id: :integer, default: nil が出力されるようになります。
    • そのため、既存プロジェクトで SQLite を使っていて、上記のような主キー定義をしている場合は、Rails アップデート後に db:schema:dump すると schema.rb の差分が増えますが、これは不具合修正に伴う「正しい差分」です。
  • 注意点:
    • これまで「なぜか AUTOINCREMENT になっていた」ことを前提にした実装・運用があった場合(通常はない想定ですが)、挙動が変わる可能性があります。
    • スキーマを schema.rb ベースで管理している SQLite プロジェクトでは、この修正以降に環境を作り直すと、id の挙動が「元の migration の意図通り」に戻ることを意識しておくとよいです。

  1. 参考情報 (あれば)

#56535 [Backport 8-1-stable] Fix PostgreSQL schema_search_path after reconnect and reset

マージ日: 2026/1/7 | 作成者: @eglitobias

  1. 概要 (1–2文で)
    Rails 8.1系のPostgreSQLアダプタで、「再接続後や接続リセット後に schema_search_path が正しく復元されない」不具合を修正するパッチを 8-1-stable ブランチにバックポートしたPRです。これにより、マルチスキーマ運用や schema_search_path を前提としたアプリで、再接続時にも一貫したスキーマ検索パスが保証されます。

  1. 変更内容の詳細

2-1. どんなバグか

対象のバグ(#56378)は、Active Record の PostgreSQL アダプタが

  • DB接続の「再接続(reconnect)」
  • 「リセット(reset)」や類似の状態リセット処理

を行った後に、本来アプリケーション側で設定していたはずの schema_search_path を正しく復元できず、デフォルト(例: "public")などに戻ってしまう、という挙動です。

その結果、

  • テナントごとにスキーマを切り替えるマルチテナント構成
  • schema_search_path = 'tenant1, public' のようにアプリ側で明示的に指定しているケース

などで、接続エラーやプールからの接続再利用をきっかけに、意図しないスキーマを参照してしまう危険がありました。

2-2. 修正内容の概要

PRの説明と diff の規模から判断すると、主な変更点は以下です。

  1. PostgreSQL アダプタ (postgresql_adapter.rb) において

    • 接続確立時・再接続時・リセット時に、内部的に保持している schema_search_path の値を用いて、DB側に SET search_path TO ... を再適用するようなロジックが追加/修正されている。
    • もしくは、Active Record が保持している設定と DB セッション側の実際の search_path がずれないよう、再同期の仕組みが強化されている。
  2. テスト (postgresql_adapter_test.rb) の追加

    • 再接続またはリセットを行った後でも、ActiveRecord::Base.connection.schema_search_path が保持している値が DB セッションに正しく反映されることを確認するテストが追加されています。

    • 想定されるテストのイメージ例(簡略):

      ruby
      def test_schema_search_path_is_preserved_after_reconnect
        conn = ActiveRecord::Base.connection
      
        conn.schema_search_path = "my_schema, public"
        assert_equal "my_schema, public", conn.schema_search_path
      
        # 再接続 or リセットを発生させる
        conn.reconnect!
      
        # 再接続後も search_path が維持されているか確認
        assert_equal "my_schema, public", conn.schema_search_path
        assert_equal "my_schema, public", conn.select_value("SHOW search_path")
      end
    • 実際のコードは多少異なる可能性がありますが、少なくとも

      • アダプタ内部が覚えている schema_search_path
      • DB側が持つ SHOW search_path の結果 の両方が期待どおりに一致することをテストしていると考えられます。
  3. CHANGELOG の更新 (activerecord/CHANGELOG.md)

    • Rails 8.1 の activerecord に関して、「PostgreSQL adapter で reconnect/reset 時の schema_search_path が正しく維持されるよう修正した」という趣旨のエントリが追加されています。
    • これにより、8.1系の変更履歴からも、当該バグが修正されたことが分かるようになっています。
  4. PostgreSQL 18 向け改善は含めない

    • オリジナルPR(#56379)には PostgreSQL 18 固有の改善も含まれていましたが、このバックポートでは それらを含めず、純粋なバグ修正部分のみ を取り込んでいます。
    • 8.1の安定性を重視し、リスクの高い機能追加や将来バージョン依存の変更は避けた形です。

  1. 影響範囲・注意点

3-1. 影響を受けるケース

以下に該当するアプリケーションは、この修正の影響(=改善)を受けます。

  • データベースに PostgreSQL を使用している
  • Active Record で schema_search_path を明示的に設定している
    • database.ymlschema_search_path を指定
    • 実行時に connection.schema_search_path = ... を変更
  • 接続プールによる再接続や、DB再起動・一時切断などが発生しうる運用

こうした状況下で、再接続以降に意図しないスキーマを参照してしまうバグが解消されます。

3-2. 互換性・リスク

  • 変更は基本的に「本来そうあるべきだった schema_search_path の保持・復元動作を正す」内容であり、正しく設定を使っているアプリにとっては後方互換的です。
  • もし既に「バグがある前提」でワークアラウンドしていた場合(例:各リクエストごとに SET search_path を手動で実行しているなど)、二重設定になっていないかを確認してください。
  • PostgreSQL 18 向けの新機能・最適化は含まれていないので、DB バージョンアップを兼ねた挙動変更はこのPRの範囲外です。

3-3. 運用上の注意

  • Rails 8.1 にこの修正を取り込んだ後は、再接続/リセット後の schema_search_path が安定しているかどうかを、
    • マルチテナント環境
    • 複数スキーマを使うテスト環境 などで一度確認しておくと安心です。
  • 特に、接続プールのタイムアウトや DB のロールオーバー(フェイルオーバー)時に、正しいスキーマでクエリが実行されているかをログや監視で確認するとよいでしょう。

  1. 参考情報 (あれば)

Rails 8.1 系で PostgreSQL を使い、schema_search_path を前提としたスキーマ切り替えをしているプロジェクトでは、この修正を取り込む価値が高い変更です。


#56533 Revert "Remove unnecessary defined? check for RubyVM::YJIT.enable"

マージ日: 2026/1/7 | 作成者: @yahonda

  1. 概要 (1-2文で)
    このPRは、「RubyVM::YJIT.enable の前に defined? チェックを削除した」前回の変更 (#56526) を取り消し、元の defined?(RubyVM::YJIT) チェック付きのコードに戻しています。Rails 起動時に YJIT を有効化する処理まわりの安全性・互換性を確保するためのリバートです。

  1. 変更内容の詳細

変更ファイルは 1つだけで、実質 1行の差分です。Rails::Application::Finisher 内で、Rails 起動時に YJIT を有効化する処理が次のように戻されています。

おおよそのイメージ:

ruby
# リバート前 (推定)
Rails::Application::Finisher.class_eval do
  initializer :enable_yjit, group: :all do
    RubyVM::YJIT.enable if Rails.application.config.yjit_enabled
  end
end

# リバート後 (今回のPRでの状態のイメージ)
Rails::Application::Finisher.class_eval do
  initializer :enable_yjit, group: :all do
    if defined?(RubyVM::YJIT) && Rails.application.config.yjit_enabled
      RubyVM::YJIT.enable
    end
  end
end

実際には if のネストやメソッドチェーンの書き方など細部は異なる可能性がありますが、本質的な変更点は次の 1点です。

  • RubyVM::YJIT.enable を実行する前に defined?(RubyVM::YJIT) を使って存在チェックを行う処理を復活させた

もともと #56526 で「不要」と判断されて削除された defined? チェックが、該当 PR のコメントで指摘された問題により再度必要と判断され、今回の PR で元に戻されています。


  1. 影響範囲・注意点
  • Ruby / 実行環境による影響

    • YJIT が存在しない Ruby (例: 3.0 以前、YJIT 未ビルドの Ruby、JRuby など) で Rails を起動する場合でも、NameError などを避けて安全に動作します。
    • defined? チェックを行うことで、「YJIT が無い環境でも config.yjit_enabled を true にしておく」ような設定があっても、例外にならず単に YJIT が有効化されない挙動に留まります。
  • 設定との関係

    • config.yjit_enabled (名称は例) 相当のフラグが true でも、RubyVM::YJIT 定数が存在しない場合は有効化されません。
    • これまで「YJIT がある前提」でアプリ側で RubyVM::YJIT.enable を直接呼んでいた場合は、このPRとは別に、アプリ自身でも同様の存在チェックを行うことが望ましいです。
  • 既存アプリへの影響

    • #56526 が取り込まれた期間に、その挙動に依存したコードを書いていなければ、実質的には「以前の Rails の挙動に戻る」だけなので、ほぼ互換的な変更です。
    • CI などで「YJIT 非対応の Ruby」と「YJIT 対応の Ruby」を混在して使っている環境では、今回のリバートにより再び安全な挙動が保証されます。

  1. 参考情報 (あれば)
  • 元の変更 PR:
    • #56526: RubyVM::YJIT.enable 呼び出し前の defined? チェック削除
  • この PR でのリバート理由:
  • Ruby YJIT について:
    • Ruby 3.1 以降で導入された JIT コンパイラ機能。RubyVM::YJIT.enable で有効化するが、ビルド時オプションや実装によっては RubyVM::YJIT 自体が存在しない場合があるため、Rails 側では defined? による安全な存在チェックが必要になります。

#56527 Remove Ruby < 3.3 compatibility code

マージ日: 2026/1/7 | 作成者: @yahonda

  1. 概要 (1-2文で)
    このPRは、Rails main ブランチが Ruby 3.3 以上を必須とする方針に合わせて、Ruby 3.2 以下向けの互換コードを削除したものです。主に SecureRandomRange#overlap?Fiber#kill 周りの分岐・ポリフィルが取り除かれています。

  1. 変更内容の詳細

全体方針

  • これまで「Ruby 3.3 にはあるが、それ以前にはない機能」を補うために書かれていたコード(条件分岐や拡張、ポリフィル)を削除し、Ruby 3.3 標準の挙動に依存する形に整理しています。
  • ファイル数は3つのみですが、76行削除 / 6行追加と、互換レイヤーの大半を消す内容です。

activesupport/lib/active_support/core_ext/securerandom.rb

背景:

  • Ruby 本体側の SecureRandom.alphanumeric メソッドのシグネチャが Ruby 3.3 以降で安定しており、parameters.size が常に 2 になることが保証されました。
    参考: https://github.com/ruby/securerandom/pull/36

これまで:

  • SecureRandom.method(:alphanumeric).parameters.size を実行し、Ruby のバージョンや実装差によって挙動が異なる場合に備えて、引数の数や呼び出し方法を分岐していた互換コードがありました。
    • 例(イメージ):
      ruby
      if SecureRandom.method(:alphanumeric).parameters.size == 1
        # 古いシグネチャ向けラッパー
      else
        # 新しいシグネチャ向け
      end

今回の変更:

  • 上記のような「parameters.size を見て分岐する」互換コードを削除し、「Ruby 3.3 標準の SecureRandom.alphanumeric がある」ことを前提にしたコードだけに整理されています。
  • 追加された数行は、3.3 以降前提での簡潔な呼び出しに合わせるための最小限のラッパーや内部利用向けの実装だと推測されます。

activesupport/lib/active_support/core_ext/range/overlap.rb

背景:

これまで:

  • ActiveSupport 側で Range#overlap? を自前実装(モンキーパッチ/拡張)し、Ruby 本体にメソッドがない環境で range1.overlap?(range2) のように呼べるようにする互換レイヤーがありました。
  • 実装イメージ:
    ruby
    class Range
      def overlap?(other)
        # 自前のオーバーラップ判定ロジック
      end
    end

今回の変更:

  • overlap.rb の中身がほぼ全削除(約 35 行削除)されており、ActiveSupport が提供していた Range#overlap? のポリフィルは Ruby 3.3 以降では不要と判断して削除されています。
  • 以後は Ruby 3.3 標準の Range#overlap? に完全依存します。

activerecord/test/cases/connection_pool_test.rb

背景:

  • 説明文にあるとおり Ruby 3.3 では Fiber#kill が導入されています。
    参考: https://bugs.ruby-lang.org/issues/595
  • Active Record のコネクションプール関連のテストでは、Fiber を強制終了する処理の有無や実装差に対応したテストコードが書かれていたと考えられます。

これまで:

  • Fiber#kill が存在しない古い Ruby でテストが通るように、respond_to? チェックや代替手段による終了処理などの条件分岐があった可能性が高いです。

今回の変更:

  • 当該ファイルから 5 行削除されており、互換目的の条件分岐やスキップ処理が取り除かれています。
  • Ruby 3.3 には Fiber#kill が必ず存在する前提のテストコードに一本化されたと考えられます。

  1. 影響範囲・注意点
  • Ruby バージョン要件

    • Rails main ブランチを利用する場合、Ruby 3.3 未満では動作しない(もしくはサポート対象外)になります。
    • 3.2 やそれ以前で Rails main を追いかけていた環境は、このPR以降ビルドやテストが失敗する可能性が高いです。
  • 互換レイヤー削除の影響

    • Range#overlap?:
      • 3.3 未満の Ruby では、ActiveSupport を読み込んでも Range#overlap? が定義されなくなります(そもそも main は 3.3 未満非対応という前提)。
      • 3.3 以上では Ruby 本体の挙動にそのまま従うため、ActiveSupport 独自実装と Ruby 本体実装の微妙な差異に依存していたコードがあると挙動が変わる可能性があります(想定としては小さいはずですが、境界条件の判定ロジックが異なる場合は注意が必要です)。
    • SecureRandom.alphanumeric:
      • SecureRandom.method(:alphanumeric).parameters の数に依存したメタプログラミング的なコードを書いている場合、Rails 側の挙動が(古い Ruby を想定した)以前と異なって見える可能性はあります。ただし通常のアプリケーション利用ではまず問題にならない変更です。
  • テストコード

    • Fiber#kill に依存するテストは Ruby 3.3 未満では動かないため、Rails main を元にバックポートテストを行っているような特殊な環境では注意が必要です。

  1. 参考情報 (あれば)

#56526 Remove unnecessary defined? check for RubyVM::YJIT.enable

マージ日: 2026/1/6 | 作成者: @yahonda

  1. 概要 (1-2文で)
    Rails main ブランチが Ruby 3.3.0 以上を必須としたことに伴い、RubyVM::YJIT.enable の存在チェック (defined?) を削除してコードを簡略化した PR です。Ruby 3.3 以降では RubyVM::YJIT.enable が常に存在するため、ガードが不要になっています。

  1. 変更内容の詳細

変更ファイルは railties/lib/rails/application/finisher.rb のみで、1行の置き換えです。

もともと以下のように、「メソッドが存在するか」を確認してから YJIT を有効化していました:

ruby
if defined?(RubyVM::YJIT.enable)
  RubyVM::YJIT.enable
end

これが、Ruby 3.3.0 以上で RubyVM::YJIT.enable が必ず存在することを前提に、単純な呼び出しに変更されています:

ruby
RubyVM::YJIT.enable

つまり、「RubyVM::YJIT に enable メソッドが定義されているか」という存在確認ロジックを削除しただけで、YJIT を有効化するという挙動自体はそのままです。

背景として:

  • Rails main ブランチは Ruby 3.3.0 を必須バージョンに変更済み
  • Ruby 3.3.0 では RubyVM::YJIT.enable が標準で追加されている

という前提により、「古い Ruby で YJIT がないかもしれない」というケースを考慮する必要がなくなったためです。


  1. 影響範囲・注意点
  • 対象バージョン

    • Rails main ブランチ(Ruby 3.3.0 以上を前提とするバージョン)でのみ有効な変更です。
    • Ruby 3.2 以前を使っている環境では、そもそもこのブランチはサポート外という前提になります。
  • 機能的な挙動

    • Rails アプリケーションの起動時に YJIT を有効にする、という挙動自体は変わりません。
    • 以前は「YJIT が存在すれば有効化」、現在は「YJIT が存在することを前提に必ず呼ぶ」という違いだけです。
  • 潜在的な注意点

    • Ruby をパッチでビルドしていて RubyVM::YJIT を意図的に削っている、など「Ruby 3.3 だが YJIT がない」という非常に特殊な環境では NameError / NoMethodError が発生する可能性があります。
    • そのようなカスタム環境を使っていない限り、通常の利用では問題になりません。

  1. 参考情報 (あれば)

#56488 Ensure version_manager_ruby_version tests work in rbenv/rvm environments

マージ日: 2026/1/6 | 作成者: @zzak

  1. 概要 (1-2文で)
    version_manager_ruby_version に関するテストが、rbenv / rvm 環境でローカル実行すると落ちてしまう問題を修正した PR です。主にテスト側での Ruby バージョン検出の前提を見直し、実行環境(rbenv/rvm)の影響を受けないようにしています。

  1. 変更内容の詳細

※実ファイル差分は要約ベースですが、挙動としては以下のような修正が行われています。

背景となる問題

Rails::Generators::GeneratorTest にある version_manager_ruby_version 周りのテストは、「こういう環境変数/実行環境のときに、Ruby のバージョン文字列をどう返すか」を検証しています。

しかし、開発者がローカルでテストを走らせると、rbenv や rvm が有効になっているため、テストが期待していない値が返り、以下のように失敗していました。

text
Expected: "ruby-3.4.0"
  Actual: "4.1.0"
...
Expected: "ruby-4.0.0-preview2"
  Actual: "4.1.0"
...
Expected: "jruby-10.0.2.0"
  Actual: "4.1.0"

ここで Actual: "4.1.0" は「実際にテストを実行している Ruby (例: 3.4.0 ではなく 4.1.0)」由来の値であり、本来テストしたい値(rvm の環境変数や、模擬的に想定したバージョン文字列)ではありません。

テストコード側の修正方針

この PR は「実際の rbenv / rvm の設定に左右されないよう、テストで使う Ruby バージョン情報を明示的にコントロールする」ようにテストコードを修正しています。

典型的には次のような対応が入ったと考えられます(実装イメージ):

  1. 環境変数を明示的にセット/リセット

    たとえば rvm 用のテストでは:

    ruby
    test "version_manager_ruby_version_with_rvm_env_var" do
      EnvUtil.with_original_env do
        ENV["RUBY_VERSION"] = "ruby-3.4.0" # あるいは RVM 特有の環境変数名
        assert_equal "ruby-3.4.0", version_manager_ruby_version
      end
    end

    のように、テスト内で環境変数を上書きし、テスト終了時に元に戻すことで、rbenv/rvm が設定した値の影響を受けないようにします。

  2. RUBY_ENGINERUBY_VERSION に依存する部分をスタブ/モック

    MRI / JRuby などの違いをテストするケースでは、実行中の Ruby 環境(例: MRI 3.x)に依存せず、あくまで「こういう値が返ってきたらどう扱うか」をテストする形に寄せます。例:

    ruby
    test "version_manager_ruby_version_with_non_mri_ruby" do
      stub_const("RUBY_ENGINE", "jruby")
      stub_const("RUBY_ENGINE_VERSION", "10.0.2.0")
    
      assert_equal "jruby-10.0.2.0", version_manager_ruby_version
    end

    実際には stub_const ではなく Rails のテストヘルパーや Object.stub / Module.prepend 等を使ったりしますが、ポイントは「実際に JRuby で動かしていなくても JRuby であるかのように振る舞わせてテストする」ことです。

  3. テスト名ごとに前提条件を明確化

    • test_version_manager_ruby_version_with_mri_ruby: RUBY_ENGINE == "ruby" を前提に、ruby-3.4.0 のような文字列を返すケース
    • test_version_manager_ruby_version_with_mri_ruby_prerelease: ruby-4.0.0-preview2 のようなプレリリース版の扱い
    • test_version_manager_ruby_version_with_rvm_env_var: rvm 特有の環境変数を元にバージョン文字列を組み立てるケース
    • test_version_manager_ruby_version_with_non_mri_ruby: JRuby など MRI 以外の Ruby エンジンの扱い

    それぞれについて、「実際の実行環境とは独立して、想定した入力 → 期待する出力」を明確にするような形に修正されています。

この結果、ローカルで rbenv / rvm を使っていても、テスト実行時にそれらの設定が直接影響せず、CI と同じ前提で安定してテストが通るようになります。


  1. 影響範囲・注意点
  • 影響範囲

    • 変更は railties/test/generators/generator_test.rb のテストコードのみであり、本体機能 (Rails の generator 本体の挙動) には影響しません。
    • version_manager_ruby_version の仕様自体は変えておらず、「どうテストするか」が変わっただけです。
  • 開発者視点でのポイント

    • rbenv / rvm を使っている開発者が bin/test test/generators/generator_test.rb をローカル実行しても、Ruby バージョンの違いによる誤ったテスト失敗が起きなくなります。
    • 今後同様のテストを書く場合も、「実行環境の Ruby バージョンや version manager に依存しないようにスタブや環境変数の明示セットを行う」という方針が参考になります。
  • 注意点

    • Ruby 本体のバージョンが上がったことでテストが壊れていたわけではなく、「テストが実行環境の設定に依存していた」ことが原因なので、同様のパターンが他のテストにもないか、今後も注意が必要です。

  1. 参考情報 (あれば)
  • 元 PR: #56365 (この PR はそのフォローアップ)
  • 関連箇所: Rails::Generators::AppBase#ruby_version や、version_manager_ruby_version 周辺の実装
  • version manager の一般的な挙動:
    • rbenv: RBENV_VERSION.ruby-version を用いてバージョンを切り替え
    • rvm: RUBY_VERSION, GEM_HOME, GEM_PATH など複数の環境変数を設定

今回の修正は、これらの「実行時に勝手に入る環境変数」にテストが振り回されないようにする、という位置づけのものです。


#56524 Fix Rails.app.revision to check git repo in app root

マージ日: 2026/1/6 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Rails.app.revision がアプリケーションのルートディレクトリではなく「現在の作業ディレクトリ」を基準に .git を探していた問題を修正し、常にアプリケーションルートの Git 情報を参照するようにした PR です。これにより、別ディレクトリから Rails アプリを起動しても正しいリビジョンが取得されます。

  1. 変更内容の詳細

問題の背景

  • #56490 で導入された Rails.app.revision は、Git のコミットハッシュなど「アプリケーションのリビジョン情報」を返すためのメソッドです。
  • しかし、その実装が「Dir.pwd(プロセスのカレントディレクトリ)」を起点に .git を探していたため、
    • cd /somewhere/else
    • bundle exec rails runner 'puts Rails.app.revision'
      のように「アプリケーションルートとは別のディレクトリ」から実行した場合に、Git リポジトリが見つからない、あるいは意図しない別リポジトリを見てしまう問題がありました。

今回の修正内容

  • .git の探索基準を「アプリケーションルート(Rails.application.root)」に変更。
  • 具体的には、Rails.app.revision 内で Git リポジトリのパスを解決する際に、Rails.application.root(=通常は config/application.rb のあるディレクトリのルート)を基準にするよう修正されています。

疑似コードイメージ(実際のコードを簡略化したイメージ):

ruby
def revision
  app_root = Rails.application.root

  # 以前: Dir.pwd から .git を探していた
  # git_dir = find_git_dir_from(Dir.pwd)

  # 修正後: アプリルートから .git を探す
  git_dir = find_git_dir_from(app_root)

  if git_dir
    # git_dir を使って HEAD のコミットなどを取得
    read_git_revision(git_dir)
  else
    nil
  end
end

これにより、Rails.app.revision は「どこから Rails を起動したか」に依存せず、常にアプリケーション自体の Git 情報を見るようになります。


  1. 影響範囲・注意点
  • 影響範囲

    • Rails.app.revision を利用している箇所(例: 独自のエラーページ、ヘルスチェックエンドポイント、APM 連携、デプロイ情報表示など)で、Git 情報の取得元が「カレントディレクトリ」から「アプリケーションルート」に固定されます。
    • これまで「たまたまカレントディレクトリ側の .git が使われていた」ケースは挙動が変わりますが、それは本来の意図した挙動への修正と言えます。
  • 注意点

    • Rails アプリのルートに Git リポジトリが存在しない(例: vendored / サブディレクトリ配備で .git がない)場合は、Rails.app.revisionnil になる可能性があります。その前提で利用しているコードでは nil ハンドリングをしておくと安全です。
    • マルチリポ構成/monorepo などで Rails アプリがサブディレクトリにあり、.git がさらに上位階層にある場合に、Rails.application.root からの探索がどう動くか(上位ディレクトリまで遡るか / サブディレクトリだけ見るか)は、本 PR の詳細実装に依存します。
      • もし monorepo で期待どおりにリビジョンが取れない場合は、Rails.application.root から上位へ辿るかどうかの仕様を確認しつつ、必要であれば別途 Issue/PR を検討する余地があります。

  1. 参考情報 (あれば)
  • 関連 PR: #56490Rails.app.revision 機能を導入した PR
  • 変更ファイル: railties/lib/rails/application.rb
  • 利用例(Rails コンソールなど):
ruby
# 現在デプロイされているアプリの Git リビジョンを確認
Rails.app.revision
# => "a1b2c3d4..."(コミットハッシュ)または nil

これにより、systemd や cron、任意のディレクトリから rails runner などを実行しても、安定して正しいアプリのリビジョンが取得できるようになります。


#56306 Fix text overflow in interstitial notes on mobile

マージ日: 2026/1/6 | 作成者: @shivamsinghchahar

  1. 概要 (1-2文で)
    Rails ガイドの「インタースティシャルな注意書き(notes)」内にある長い <code> テキストが、モバイル表示時に横にはみ出してしまう問題を CSS で修正した PRです。flex コンテナ内で段落が正しく縮小されるようにし、テキストのオーバーフローと横スクロールを防いでいます。

  1. 変更内容の詳細

問題の背景

具体的な修正

変更ファイル: guides/assets/stylesrc/components/_code-container.scss

  • .interstitial 内のテキストコンテナに overflow: hidden; を 1 行追加(差分は +1 行のみ)。

    概念的には次のような変更です(イメージ):

    scss
    .interstitial p {
      overflow: hidden; // 今回追加された行
    }

    実際にどのセレクタに付いているかはファイル内容次第ですが、

    • 「インタースティシャル内の段落要素」に overflow: hidden を設定し、
    • その要素が Block Formatting Context (BFC) を形成するようにしています。

なぜこれで直るのか(CSS/Flexbox 的な説明)

  • flex アイテム(ここでは <p>)の min-width: auto は、コンテンツのサイズをもとに「これ以上小さくならない」幅として解釈されます。
  • ただし、そのアイテムが独立した Block Formatting Context を持つと、min-width の計算方法が変わり、flex コンテナ内でより小さく縮めることが可能になります。
  • overflow: hidden を指定すると、そのブロック要素は BFC を確立します。
  • 結果として:
    • 段落が親の幅に合わせて縮む
    • 長い <code> を含んでいても、ボックス外へはみ出さない
    • モバイル表示時の横スクロール・クリップが解消される

PR 説明にある Before/After のスクリーンショットも、この動作の違いを示しています。


  1. 影響範囲・注意点

影響範囲

  • 影響対象は Rails Guides の「インタースティシャル」なメッセージ(Note, Warning など)の中にあるテキスト部分です。
  • 特に、モバイルや狭いウィンドウ幅で、長い 1 行の <code> を含む段落のレイアウトが改善されます。
  • 変更は Guides 用の SCSS に 1 行追加されただけであり、Rails 本体のランタイムコードや API には一切影響しません。

注意点

  • overflow: hidden により、極端に長い 1 行のコードが折り返されない場合、親要素幅を超えた部分が見えなくなる可能性があります。
    • ただし、現状は「横スクロールかつ見切れ」だった状態を、「横にはみ出さない+BFC によってより適切に折り返される」形に改善するのが目的で、そのトレードオフは受け入れられると判断されています。
  • テキスト選択やアクセシビリティへの影響は軽微と考えられますが、今後さらに改善するなら:
    • overflow-wrap: break-word;word-break などと組み合わせて、長い識別子やコマンドを適切に折り返す
    • コードブロックのフォントサイズ調整や code 要素専用の line wrapping ポリシー追加 などの追加調整も検討余地があります。

  1. 参考情報 (あれば)

この PR は、Rails 本体ではなく「ガイドの見た目」に関する小さなバグフィックスであり、既存アプリケーションへの影響はありません。


#56379 fix: Reset the schema_search_path during pg reconnect and reset

マージ日: 2026/1/6 | 作成者: @eglitobias

  1. 概要 (1-2文で)
    PostgreSQL / PostGIS アダプタで、接続リセットや再接続後に schema_search_path が再適用されず、デフォルトの "$user", public に戻ってしまうバグを修正した PR です。Rails 8.1 以降で reconnect! やプール経由のリセットを行っても、database.yml で設定した schema_search_path が確実に再設定されるようになります。

  1. 変更内容の詳細

問題の原因

  • Rails 8.1 で ActiveRecord::Base.connection.reconnect! などを呼ぶと、新しい PostgreSQL セッションが作られます。
  • PostgreSQL のセッションが新しくなると、search_path などセッションレベルの設定はデフォルトにリセットされます。
  • 一方で、Rails の PostgreSQLAdapter は、前回適用した @schema_search_path を Ruby 側でキャッシュしており、schema_search_path= を呼ぶ際に
    ruby
    return if new_path == @schema_search_path
    のようなガードで「前と同じなら何もしない」という最適化をしています。
  • セッションが変わって DB 側の search_path はリセットされているのに、Ruby 側では @schema_search_path が古い値のまま残っているため、「同じ値だ」と誤認して SET search_path ... を実行しない、という不整合が起きていました。
  • その結果、PostgreSQL はデフォルトの "$user", public を使い続けてしまい、マルチスキーマ構成のアプリでテーブルが見つからない等の問題が発生していました。

具体的な修正内容

修正のポイントは、「セッション状態が無効になったタイミングで、Ruby 側キャッシュ @schema_search_path をクリアする」ことです。

対象となるタイミングは2つです:

  1. PG::Connection#reset を使って再接続する時
  2. DISCARD ALL でセッションをリセットする時

PR では、PostgreSQL アダプタ内の該当コードパスに、@schema_search_path = nil を追加することで、次に configure_connection / schema_search_path= が呼ばれた際に、必ず SET search_path ... が流れるようにしています。

イメージとしては以下のような流れになります(擬似コード):

ruby
def reset!
  # 以前: ここで PG connection reset だけしていた
  @raw_connection.reset
  # 修正後: セッション状態がリセットされたので、キャッシュも捨てる
  @schema_search_path = nil
  configure_connection # ここで再度 search_path を含む設定が流れる
end

def reset_session
  execute("DISCARD ALL")
  # DISCARD ALL で search_path も消えるので、キャッシュも消す
  @schema_search_path = nil
end

schema_statements.rb 側の変更 (+3/-1) は、schema_search_path 関連の振る舞いをテストや他のロジックと整合させるための軽微な修正(キャッシュ処理や accessor 周りの整合性改善)です。

テスト

activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb に約 55 行分のテストが追加され、以下を確認しています:

  • 接続確立後に schema_search_path を設定
  • reconnect!(あるいはプール経由のリセット)を実行
  • その後もクエリが期待したスキーマを参照していること
    → 実質的には、リセット・再接続後に search_path が Rails 設定どおりに戻っていることを検証

  1. 影響範囲・注意点
  • 影響を受けるのは PostgreSQL / PostGIS アダプタのみです。他の DB アダプタには影響しません。
  • 主に以下のようなケースで恩恵があります:
    • database.ymlschema_search_path に複数スキーマを指定している
    • 接続プールのアイドル・タイムアウト、reconnect!, DB 再起動などが起こる運用をしている
  • 今まで:
    • セッション再確立後、search_path"$user", public に戻っても Rails 側が気づかず、そのまま実行
    • スキーマが異なることで「テーブルが存在しない」「間違ったスキーマのテーブルにアクセスする」などの不具合が起こりうる
  • この PR 適用後:
    • リセット・再接続後に @schema_search_path が必ず nil になるため、最初の configure_connection で必ず SET search_path が走る
    • 既存の「不要な SET search_path を避ける」ためのガードロジックは維持されるので、通常時の余計なクエリ増加は最小限です
  • すでに DB レベル / ロールレベルで search_path を設定してワークアラウンドしている場合:
    • その設定は引き続き有効ですが、database.ymlschema_search_path も正しく機能するようになります
    • 両方で設定している場合は、どちらを正とするか運用ポリシーを整理しておくとよいです

  1. 参考情報 (あれば)
  • 関連 issue:
    • #56378 (バグ報告)
    • #56382 (フォローアップ・ディスカッション用)
  • 対象バージョン:
    • 説明では Rails 8.1 の挙動に言及されていますが、実際には「PG アダプタのキャッシュと再接続の相互作用」による問題のため、8.1 系以降でこの修正が入る形になります。
  • 既知のワークアラウンド:
    • database.yml ではなく、PostgreSQL 側で ALTER ROLE ... SET search_path = ...;ALTER DATABASE ... SET search_path = ...; を使う
      → この PR 後は、基本的に database.yml での設定だけで期待どおりに動作する想定です。

#56447 Fix enum validation to allow Float values

マージ日: 2026/1/6 | 作成者: @Saidbek

  1. 概要 (1-2文で)
    Rails 8.1 系で導入された enum 定義値のバリデーションに不備があり、Float を使った enum が ArgumentError で落ちるようになっていた問題を修正する PRです。Rails 7.x や 8.0.x で動いていた「Float 値の enum 定義」を、8.1.1 以降でも再び利用できるようにします。

  1. 変更内容の詳細

問題の背景

Rails 8.1.0 で「enum にシンボル値を使えるようにする」変更(commit 2dc080f2b4)が入り、その過程で「enum 定義値の型チェック」が強化されました。

このとき、許可する型として

  • boolean
  • integer
  • symbol
  • string

などは想定されていましたが、Float が許可リストに含まれていなかったため、以下のような従来から存在したコードが 8.1.1 でエラーになる、という後方互換性のない挙動が生じていました。

ruby
class Product < ApplicationRecord
  enum :rating, { low: 0.0, medium: 0.5, high: 1.0 }, prefix: true
end

これを Rails 8.1.1 で読み込むと、次のようなエラーが発生していました:

text
ArgumentError: Enum values {:low=>0.0, :medium=>0.5, :high=>1.0} must be only booleans, integers, floats, symbols or strings, got: Float

エラーメッセージの文言自体は「floats を許可」と書いているにもかかわらず、実装側で Float クラスが許可対象に含まれていないという実装バグです。

具体的な修正内容

1) enum の型バリデーションに Float を追加

対象: activerecord/lib/active_record/enum.rb

enum の値の型をチェックしている部分で、許可される型として Float を追加しています。実際の変更は +2/-2 行と小さいですが、意味としては

  • 「enum に使える値の型」に Float を正式に含める

という修正です。

これにより、以下のような定義が再び有効になります:

ruby
class Product < ApplicationRecord
  enum :rating, { low: 0.0, medium: 0.5, high: 1.0 }, prefix: true
end

2) テストの追加

対象: activerecord/test/cases/enum_test.rb (+14/-1)

  • Float を使った enum 定義がエラーにならず、期待通りに動作することを保証するテストが追加されています。
  • これにより、今後 enum の型チェック実装を変更しても Float サポートを誤って壊さないように回帰テストとしてカバーしています。

3) スキーマの調整

対象: activerecord/test/schema/schema.rb (+1)

  • テスト用の schema に、Float enum を試すためのカラム(おそらく float 型 or decimal 型のカラム)が 1 行だけ追加されています。
  • 実運用とは無関係で、テスト環境専用の最小限のスキーマ変更です。

  1. 影響範囲・注意点

影響範囲

  • 影響を受けるのは:
    • Rails 8.1.0 以降で「Float 値の enum 定義」をしているアプリケーション
  • この PR による効果:
    • 8.1.0/8.1.1 で発生していた ArgumentError が解消され、Rails 7.0.6 / 7.2.3 / 8.0.4 と同じように Float enum が利用できるようになります。
  • 互換性:
    • もともと過去バージョンで動いていたコードを復活させる修正なので、後方互換性を回復する変更です。
    • 新たな破壊的変更は導入していません。

注意点・設計的な懸念

  • Float を enum に使うこと自体は、浮動小数点の丸め誤差や比較の問題があるため、一般論としては避けるべきケースが多いです(decimal カラム + integer enum などで表現するほうが堅牢なことが多い)。
  • とはいえ、既に DB に Float として保存されている enum 的な値を扱う既存アプリや、特定用途では Float enum を使っているコードが存在するため、「サポートを突然打ち切る」のではなく、従来どおりサポートする方向でバグ修正を行った、という位置づけです。
  • 本 PR では挙動自体(保存・読み出しの仕方など)は変えておらず、「型チェックで弾かない」ように修正しているだけです。

  1. 参考情報 (あれば)
  • 対応している issue: https://github.com/rails/rails/issues/56446
  • 問題の原因となった変更(enum のシンボル値サポート): commit 2dc080f2b4 (Rails 8.1.0 で導入)
  • エラーメッセージ:
    • Enum values {...} must be only booleans, integers, floats, symbols or strings, got: Float
      → 文言上は floats OK と書きつつ、実装で Float を許可していなかった点を修正する PR。

#54468 Make ActiveStorage::Service responsible for checksums

マージ日: 2026/1/6 | 作成者: @mrpasquini

  1. 概要 (1-2文で)
    Active Storage の「どのハッシュアルゴリズムでチェックサム(整合性チェック)を計算するか」という責務を ActiveStorage::Service 側に集約し、サービスごとに適切なアルゴリズムを選べるようにした PR です。併せて S3 サービスで SHA256 をサポートし、ダウンロード検証ロジックや JS 側のダイレクトアップロード用チェックサム計算も整理・拡張されています。

  1. 変更内容の詳細

2-1. チェックサム計算の責務移譲

これまで

  • Blob 側が calculate_checksum_in_chunks という private メソッドでチェックサムを計算していた。
  • サービスや他クラスが直接 OpenSSL::Digest::MD5ActiveStorage.checksum_implementation に依存していた。

これから

  • サービスクラス (ActiveStorage::Service) に新しい public メソッドが追加されています:
    • calculate_checksum(io)
      • ストレージサービスが、与えられた IO から適切なアルゴリズムでチェックサムを計算する窓口になります。
    • checksum_implementation
      • デフォルト実装は OpenSSL::Digest::MD5 を返し、従来通り MD5 を使うことで後方互換性を担保。
      • 各サービス実装でオーバーライドすることで、別のアルゴリズム(例: SHA256)に差し替え可能。

これにより、アプリや Active Storage の他クラスは「どのダイジェストクラスを使うか」を意識せず、サービスの API のみを呼べばよくなります。

2-2. ActiveStorage::Downloader の廃止とサービス基底クラスへの集約

  • ActiveStorage::Downloader クラスが削除されました。
  • 代わりに、基底 ActiveStorage::Service に private メソッドが追加されています:
    • download_and_verify_tempfile(...)(名前は PR 説明より)
      • ファイルを一時ファイルとしてダウンロードし、
      • サービス固有の calculate_checksum でチェックサムを計算・検証する処理をひとまとめにしたもの。
  • これにより、ダウンロード+整合性検証ロジックがサービス層の中に閉じ、外部に漏れる責務が減っています。

2-3. 各サービスの修正 (Disk / S3 など)

Disk サービス (disk_service.rb)

  • 基本的には新しい API (calculate_checksum, checksum_implementation) に沿うようにリファクタ。
  • ローカルディスク上のファイルでも、今後アルゴリズムを変えやすい構造に。

S3 サービス (s3_service.rb)

  • SHA256 サポートが追加されました。
    • S3 の仕様上、MD5 以外の「コンテンツチェックサム」を公式にサポートしており、MD5 非推奨かつ FIPS 非互換という背景から SHA256 対応を追加。
  • サービスクラスが自前で OpenSSL::Digest::MD5 を直接触らず、checksum_implementation 経由でアルゴリズムを取得するよう変更。
  • ダイレクトアップロード(クライアントから S3 へ直接 PUT するパターン)についても、SHA256 チェックサムを扱えるようになっています。

2-4. JS 側(ダイレクトアップロード)のリファクタとアルゴリズム分離

activestorage の JavaScript 部分にかなりの変更が入っています。

主なポイント:

  1. アルゴリズムを個別ファイルに分離

    • algorithms/md5_algorithm.js 新規追加
    • algorithms/sha256_algorithm.js 新規追加
    • これにより、JS 内で「どのハッシュアルゴリズムを使うか」を差し替えやすくなっています。
  2. file_checksum.js の変更

    • これまで 1 つの実装に MD5 固定で書かれていた処理が、

    • 「アルゴリズム戦略(MD5 / SHA256 など)」を切り替えられるようにリファクタされています。

    • 例:擬似コードイメージ

      js
      import { MD5Algorithm } from "./algorithms/md5_algorithm"
      import { SHA256Algorithm } from "./algorithms/sha256_algorithm"
      
      function createAlgorithm(name) {
        switch (name) {
          case "sha256":
            return new SHA256Algorithm()
          case "md5":
          default:
            return new MD5Algorithm()
        }
      }
      
      export function calculateFileChecksum(file, algorithmName = "md5") {
        const algorithm = createAlgorithm(algorithmName)
        // file をチャンク単位で読み、algorithm.update(...) していき、
        // algorithm.digest() で結果を返す、という構造に整理。
      }
  3. direct_upload.js, direct_upload_controller.js

    • ダイレクトアップロード時に使用するチェックサム計算の呼び出しを、上記の「アルゴリズム分離」構造に合わせて修正。
    • サーバー側 (S3 サービス設定など) に合わせて、JS 側でも MD5 / SHA256 を選択できるような構造。
  4. activestorage.esm.js, activestorage.js

    • 上記変更を反映するためにビルドされているバンドルファイルに大量の差分が発生しています(+482/-18, +475/-18)。

2-5. ActionView 側の変更(フォームヘルパ)

  • form_tag_helper.rb とそのテスト (form_helper_test.rb, form_tag_helper_test.rb) が微修正されています。
  • 主な目的は ダイレクトアップロード関連の hidden フィールド / メタ情報の調整で、サーバー側が期待するチェックサムアルゴリズムや値を正しく送るための対応と考えられます。

2-6. テスト・ドキュメント・その他

  • activestorage/test/service/s3_service_test.rb に SHA256 対応などをカバーするテストが大量追加。
  • direct_uploads_controller_test.rb にも新しいダイレクトアップロード仕様を検証するテストが追加。
  • activestorage/CHANGELOG.md に今回の変更点が追記。
  • guides/source/active_storage_overview.md にも 1 行追記があり、アルゴリズムやチェックサム関連の挙動に触れている可能性があります。
  • package.json のバージョンやビルド関連定義が僅かに変更されています(JS 変更への追随)。

  1. 影響範囲・注意点

3-1. 影響範囲

  • Active Storage を利用しているアプリ全般

    • 内部実装の責務分担が変わっているため、もしアプリ側で
      • ActiveStorage::Blob の private メソッド(calculate_checksum_in_chunks など)に依存していたり、
      • ActiveStorage::Downloader を直接使っていたり、
      • サービスクラスを独自実装して MD5 前提のコードを書いている 場合は影響を受けます。
  • 独自の Active Storage サービスを実装している場合

    • 新しく追加された calculate_checksumchecksum_implementation に沿うように実装を見直す必要があります。
    • とはいえデフォルトの checksum_implementation は MD5 を返すため、単純な独自サービスなら「そのままでも動く」が、将来的なアルゴリズム切り替えを見据えて対応しておくのが望ましいです。
  • ダイレクトアップロードを使っている場合

    • JS 側のビルド成果物・ロジックが変わっているので、activestorage.js を独自に上書き・フォークしている場合はマージが必要です。
    • S3 ダイレクトアップロードでチェックサム検証をしている場合、SHA256 を選ぶ構成も可能になりますが、その分設定・実装の整合性に注意。

3-2. 後方互換性と注意点

  • デフォルトの checksum_implementationOpenSSL::Digest::MD5 のままなので、
    • 何もカスタマイズしていない一般的なアプリは、そのままでも挙動はほぼ変わりません
  • ただし以下のようなケースは要確認:
    1. MD5 固定でチェックサム値を解釈している自前コード
      • 将来、サービス側が SHA256 などに切り替えた場合、アプリ側のロジックも追従する必要があります。
    2. Active Storage の内部クラスに直接依存している場合
      • ActiveStorage::Downloader は削除されたため、直接利用していた場合は ActiveStorage::Blob など公開 API 経由に切り替える必要があります。
    3. FIPS 対応環境
      • この PR 自体は「MD5 をサービス抽象層の裏側に閉じ込めた」段階であり、完全に MD5 を排除したわけではありません。
      • ただし、今後 checksum_implementation を上書きすることで MD5 以外のアルゴリズムに切り替えられる道筋ができたため、FIPS 準拠構成を作りやすくなっています。
      • 実際に FIPS 準拠をする際は、利用中のサービス実装が MD5 を前提としていないかを確認する必要があります。

  1. 参考情報 (あれば)

要点としては「チェックサム計算の責務を ActiveStorage::Service に集約し、アルゴリズムを差し替え可能にした上で、S3 で SHA256 をサポートし、JS 側もそれに対応できるようにした変更」と捉えると理解しやすいです。


#56517 Fix deprecation horizon for AJ adapters

マージ日: 2026/1/5 | 作成者: @morgoth

  1. 概要 (1-2文で)
    Active Job の backburner / sneakers キューアダプタについて、「いつ非推奨になるか」のバージョン表記を修正し、Rails 8.2 で非推奨とする方針に揃えた PR です。実装そのものの挙動変更ではなく、非推奨スケジュール(deprecation horizon)の明確化・整合性のための微修正です。

  1. 変更内容の詳細

2-1. Active Job アダプタの非推奨バージョン表記の修正

変更ファイル:

  • activejob/lib/active_job/queue_adapters/backburner_adapter.rb
  • activejob/lib/active_job/queue_adapters/sneakers_adapter.rb

これらのアダプタには、非推奨を示すメッセージ(またはコメント)の中に「どの Rails バージョンで削除・本格非推奨とするか」を示す deprecation horizon が記載されています。この PR では、そのバージョン指定を 「8.2 で非推奨になる」 形で統一するよう1行ずつ修正しています。

イメージとしては、以下のような変更です(実際の文言は多少異なる可能性がありますが、意味としてはこうした修正です):

ruby
# 変更前(例)
ActiveSupport::Deprecation.warn(
  "backburner adapter will be deprecated in Rails 8.1."
)

# 変更後(例)
ActiveSupport::Deprecation.warn(
  "backburner adapter will be deprecated in Rails 8.2."
)

あるいは、コメントベースで horizon を書いている場合も同様に「8.2」に修正されています。

2-2. テストの修正

変更ファイル:

  • activejob/test/cases/adapter_test.rb

テスト側でも、非推奨メッセージの期待値や、バージョン番号に依存したアサーションが存在しており、それらを 8.2 に合わせて +4/-4 行 の修正を行っています。

こちらもイメージとしては:

ruby
# 変更前(例)
assert_deprecated("will be deprecated in Rails 8.1") do
  # ...
end

# 変更後(例)
assert_deprecated("will be deprecated in Rails 8.2") do
  # ...
end

機能や API の追加・削除ではなく、「どのバージョンで deprecated 扱いとするか」に関するメタ情報の更新と、それに追随するテストの更新です。


  1. 影響範囲・注意点
  • アプリケーションの実行時挙動への影響はほぼない
    ロジックやインターフェイスは変わっておらず、既存コードはそのまま動きます。
    変更されたのは「非推奨に関するメッセージ/バージョン情報」と、それに対応するテストのみです。

  • Active Job で backburner / sneakers を使っているプロジェクトへの影響

    • これらのアダプタは、Rails コアとしては今後廃止方向で、Rails 8.2 のタイミングで非推奨とされることが改めて明確にされました。
    • すでに以前の PR (#53334, #53335) で「非推奨にしていく」流れが示されており、この PR はその horizon の整合性をとるフォローアップです。
    • 長期的には、これらのアダプタからの移行(例: Sidekiq, Resque, Delayed Job など別のキューアダプタ)を検討すべきタイミングである、という示唆になります。
  • gem メンテナ向けの注意点

    • backburner や sneakers の Rails 連携を外部 gem として提供している場合、Rails 8.2 以降でコアから削除される可能性を見越して、独立したアダプタ gem として維持するか、あるいはサポート終了に向けてアナウンスを進める必要があります。
    • サードパーティ側で「どの Rails バージョンまでサポートするか」のポリシーを決める際に、この horizon 情報が参考になります。

  1. 参考情報 (あれば)

これらを読むことで、「なぜ backburner / sneakers がコアから外される流れになっているのか」「どのバージョンでどう扱うか」といった背景が確認できます。


#56519 Use the random suffix in the atomic temp file name

マージ日: 2026/1/5 | 作成者: @djmb

  1. 概要 (1-2文で)
    File.atomic_write で一時ファイル名にランダムな suffix が反映されていなかった不具合を修正し、同一ファイルへ並行書き込みした際に一時ファイル名が衝突しないようにしました。これにより、マルチプロセス/マルチスレッド環境での原子的なファイル書き込みの安全性が向上しています。

  1. 変更内容の詳細

背景

過去のコミット(f781cc50e5b2...)で、一時ファイル名に付与されるはずの suffix が実際のファイル名に反映されない変更が入っていました。その結果、File.atomic_write("same_path") を複数プロセス・スレッドから同時に実行すると、一時ファイル名が同じになり衝突(上書き・エラー)の可能性がありました。

今回の修正内容

対象ファイル:

  • activesupport/lib/active_support/core_ext/file/atomic.rb
  • activesupport/test/core_ext/file_test.rb

核心となる修正は 1 行で、一時ファイル名を生成する箇所で「suffix をきちんとファイル名に含める」ようにしています。

イメージとしては、以下のような挙動になります(実際のコードは簡略化):

ruby
# 修正後イメージ
def atomic_write(file_name, temp_suffix: ".#{Process.pid}-#{rand(1000000)}")
  # 例: file_name = "output.txt"
  # temp_suffix = ".12345-987654" など
  temp_file_name = "#{file_name}.#{Process.pid}-#{rand(1000000)}" # suffix が反映される
  # => "output.txt.12345-987654"
end

以前は、temp_suffix オプション自体やランダム suffix 用の値は計算されているのに、最終的な一時ファイル名にその値が付かず、実質的に「同じパス+固定的な suffix(あるいは suffix なし)」の状態になっていました。

テスト (activesupport/test/core_ext/file_test.rb) では、

  • ランダム suffix が一時ファイル名に含まれていること
  • 複数回/並行実行しても一時ファイル名が衝突しないこと
    を検証するテストケースが追加されています。
    これにより、回帰バグを防ぐためのカバレッジが確保されています。

  1. 影響範囲・注意点
  • 影響範囲:
    • ActiveSupportFile.atomic_write を利用しているコードが対象です。
    • 特に、同じパスに対して複数プロセス・スレッドから並行して atomic_write を行うような処理(例: キャッシュファイル生成、ログローテーション的な処理、自前の設定ファイル更新など)で、以前より安全になります。
  • 破壊的変更の有無:
    • 一時ファイル「名」がこれまでより一意性の高いランダム suffix 付きになるため、
      • 一時ファイルのファイル名パターンに依存した処理(ディレクトリをスキャンして、一時ファイルを独自ルールでクリーンアップしているなど)を書いている場合は、パターンが変わっていないか確認が必要です。
    • ただし File.atomic_write の設計上、「一時ファイルは内部実装の詳細」とみなされることが多く、この挙動に依存したコードは通常は存在しない想定です。
  • 不具合回避の観点:
    • 以前のバージョンで「ときどきファイル内容が欠損する」「競合して書き込みに失敗する」などの現象があり、File.atomic_write を疑っていたケースでは、この修正で改善される可能性があります。
    • CI や本番環境で並行書き込み時の断続的な失敗が発生していた場合は、Rails をこの修正を含むバージョンに上げることで事象が解消されるか確認する価値があります。

  1. 参考情報 (あれば)

#56522 Don't set Vary when forgery protection is skipped

マージ日: 2026/1/5 | 作成者: @djmb

  1. 概要 (1-2文で)
    このPRは、「リクエストフォージェリ保護(CSRF保護)」をスキップしたアクションでは、レスポンスヘッダ Vary"Sec-Fetch-Site" を追加しないようにする変更です。これにより、CSRF保護が無効なエンドポイントで不要なキャッシュ分割(Varyによるバリアント増加)が起こらないようになります。

  1. 変更内容の詳細

何が変わったか

対象ファイル:

  • actionpack/lib/action_controller/metal/request_forgery_protection.rb
  • actionpack/test/controller/request_forgery_protection_test.rb

主なポイント:

  1. CSRF保護をスキップしている場合は Vary: Sec-Fetch-Site を付けない
    これまでの実装では、CSRF保護の仕組みの一部として Sec-Fetch-Site ヘッダを見て挙動を変えるため、レスポンスヘッダに:

    http
    Vary: Sec-Fetch-Site

    を追加していました。
    このPRでは、次のようなケースでは Vary"Sec-Fetch-Site" を追加しない ように条件分岐が強化されています。

    ruby
    class PublicController < ApplicationController
      # CSRF保護をスキップ
      skip_forgery_protection
    
      def index
        render plain: "public"
      end
    end

    上記のように skip_forgery_protection しているアクション / コントローラでは、レスポンスヘッダに Vary: Sec-Fetch-Site が入らなくなります。

  2. テストの追加
    request_forgery_protection_test.rb に、次のようなパターンを検証するテストが追加されています。

    • CSRF保護が 有効 なアクションのレスポンスには Vary: Sec-Fetch-Site が含まれること
    • skip_forgery_protection などで 保護をスキップしている アクションには Vary: Sec-Fetch-Site が含まれないこと

    ざっくりしたイメージコード(実際のテストはもう少し細かいですが):

    ruby
    test "sets Vary Sec-Fetch-Site when forgery protection is enabled" do
      get :protected_action
      assert_includes response.headers["Vary"], "Sec-Fetch-Site"
    end
    
    test "does not set Vary Sec-Fetch-Site when forgery protection is skipped" do
      get :unprotected_action
      assert_not_includes (response.headers["Vary"] || ""), "Sec-Fetch-Site"
    end

  1. 影響範囲・注意点
  • 影響するケース

    • コントローラ/アクション単位で skip_forgery_protectionskip_before_action :verify_authenticity_token を利用しているエンドポイント。
    • 特にCDNやリバースプロキシ、Railsのキャッシュ機構などで Vary ヘッダを用いてレスポンスキャッシュを制御している場合に挙動が変わります。
  • 実質的な挙動変化

    • CSRF保護が有効なエンドポイント
      → これまで通り Vary: Sec-Fetch-Site が付き、ブラウザからの Sec-Fetch-Site の値によってキャッシュが分割され得ます。
    • CSRF保護が無効なエンドポイント
      → 今後は Sec-Fetch-Site によるバリアント分割が行われなくなり、キャッシュキーがシンプルになります。 → 逆に言うと、「CSRF保護を無効にしているのに Sec-Fetch-Site でキャッシュを分ける」という、やや意味の薄いオーバーヘッドが解消されます。
  • セキュリティ面

    • CSRF保護が「スキップされている」場合のみ Vary から除く挙動なので、保護が必要なエンドポイントの安全性は維持されます。
    • このPRは、「CSRF保護機能に依存していないエンドポイントでは、Sec-Fetch-Siteをキャッシュ条件にしない」という合理化であり、保護自体を弱めるものではありません。
  • 互換性

    • 既に skip_forgery_protection を前提に、「Vary: Sec-Fetch-Site が付くこと」を利用した特殊なキャッシュ設定をしている場合は、挙動が変わる可能性がありますが、そのようなユースケースはかなりレアと思われます。
    • 一般的なRailsアプリでは、この変更により「不要なVaryが減る」以上の影響はほぼありません。

  1. 参考情報 (あれば)

#56518 Remove deprecated sidekiq Active Job adapter

マージ日: 2026/1/5 | 作成者: @morgoth

  1. 概要 (1–2文で)
    Rails 本体に含まれていた「非推奨の Sidekiq ActiveJob アダプタ」が削除され、今後は Sidekiq gem 側が提供するアダプタを使う前提になりました。これにより Rails コアから Sidekiq 依存・コード・テストがほぼ一掃されています。

  1. 変更内容の詳細

2-1. Rails 同梱の Sidekiq アダプタ削除

以下のファイルが事実上削除されています:

  • activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb
    → 94行すべて削除。Rails が内部で ActiveJob::QueueAdapters::SidekiqAdapter を実装・提供することはなくなります。

  • 関連テスト・サポートコード

    • activejob/test/adapters/sidekiq.rb
    • activejob/test/cases/adapter_test.rb 内の Sidekiq 関連部分
    • activejob/test/cases/test_case_test.rb の Sidekiq 部分
    • activejob/test/integration/queuing_test.rb の Sidekiq 部分
    • activejob/test/support/integration/adapters/sidekiq.rb → Sidekiq 向けの ActiveJob 統合テスト一式が削除されています。

2-2. queue_adapters 周りの調整

  • activejob/lib/active_job/queue_adapters.rb
    Sidekiq アダプタの登録・関連コードが削除/調整されています(queue_adapter = :sidekiq などを Rails 本体が面倒みる前提がなくなる)。

2-3. Gem / Rake / ドキュメントの更新

  • Gemfile / Gemfile.lock
    Sidekiq に関する依存が削除されています(Rails 本体の開発・テスト用依存からも外れた)。

  • Rakefile, activejob/Rakefile
    Sidekiq を前提としたタスクやロード処理が1行ずつ調整されています(Sidekiq 関連のテストタスクなどが消えたことへの追随)。

  • activejob/CHANGELOG.md

    • 「Sidekiq ActiveJob adapter を削除した」旨が追記されています。
      → この PR が正式に変更として記録され、将来のリリースノートにも載る位置づけ。
  • activejob/README.md / ガイド類

    • guides/source/active_job_basics.md
    • guides/source/configuring.md
    • guides/source/contributing_to_ruby_on_rails.md
      ActiveJob の利用方法・設定例・貢献ガイドから、Rails 同梱の Sidekiq アダプタに関する記述が削除・書き換えられています。
      例として:
    • config.active_job.queue_adapter = :sidekiq のような記述が、必要に応じて「Sidekiq gem が提供するアダプタを使う」前提の説明に整理されているはずです。
  • railties/test/application/active_job_adapter_test.rb
    デフォルトアダプタや各アダプタに関するアプリケーションテストから、Sidekiq に関するアサーションが1行削除され、他のアダプタに合わせた形に整理されています。


  1. 影響範囲・注意点

3-1. アダプタの定義元が Rails → Sidekiq gem に一本化

これまで:

ruby
# (Rails 同梱の sidekiq adapter を利用していた)
config.active_job.queue_adapter = :sidekiq

今後:

  • 同じ書き方自体は基本的にそのまま使えるが、アダプタの実装は「sidekiq gem 側」によって提供されることになります。
  • つまり:
    • gem 'sidekiq' を入れていない環境では、queue_adapter = :sidekiq の設定が解決できなくなり、起動時 or 実行時にエラーになる可能性があります。
    • Rails をアップデートしたのに Sidekiq gem を古いままにしていると、アダプタのクラス名・実装の食い違いが起こり得ます。

対応の基本方針は:

  1. Gemfile に Sidekiq を明示的に記述する:

    ruby
    gem 'sidekiq', '~> 7.0' # 例: Rails のサポート範囲に合わせる
  2. Sidekiq のドキュメントに沿って ActiveJob 連携を行う
    → アダプタのクラス名・設定方法が Sidekiq 側のガイドに記載されているので、Rails ガイドだけでなく Sidekiq の README を必ず確認する。

3-2. 自前で ActiveJob::QueueAdapters::SidekiqAdapter に依存している場合

以前、Rails が提供していた ActiveJob::QueueAdapters::SidekiqAdapter クラスに直接依存していたコード(たとえば独自のラッパ・テスト・モンキーパッチなど)は、そのままでは動かなくなります。

例:

ruby
# こうした参照は要確認
ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper

今後は:

  • Sidekiq gem 側のアダプタクラス・ラッパクラス名に合わせて修正する必要があります。
  • 実装詳細(内部クラスや JobWrapper の構造など)も Rails ではなく Sidekiq の責務になるため、
    • Rails 側では互換性は保証されず、
    • Sidekiq のバージョンアップポリシーに従う形になります。

3-3. テスト環境・CI への影響

  • Rails 本体のテストスイートから Sidekiq 関連のテストが削除されたため、
    Rails バージョンアップ後に「Sidekiq × ActiveJob の動作確認」を行いたい場合は、自身のアプリ側で統合テストを用意しておく必要があります。
  • CI で SIDEKIQ フラグなどを使っていた場合(Rails 本体のテストに依存していたケース等)は、不要になった設定がないか見直してください。

  1. 参考情報 (あれば)

実務的には、「Rails だけで Sidekiq アダプタが自動でついてくる」前提を捨て、Sidekiq gem を明示的に導入し、そのドキュメントに従って ActiveJob 連携を行う、というスタンスに切り替える必要があります。


#56516 Fix Rails::Application usage of error reporter middleware

マージ日: 2026/1/5 | 作成者: @etiennebarrie

  1. 概要 (1-2文で)
    Rails::Application がエラーレポーター用ミドルウェアを誤った形で呼び出していた問題を修正し、error_reporter に渡したコンテキスト情報が正しく保持されるようになりました。これにより、ミドルウェア経由のエラー報告でも report と同等の情報が利用できます。

  1. 変更内容の詳細

2-1. 問題のポイント

  • ActiveSupport::ErrorReporter には「ミドルウェアとして差し込める機構」があり、
    • report メソッド
    • middleware 経由の報告
      で同じインターフェイス(同じ引数構造 / 返り値)を想定しています。
  • しかし Rails::Application 側でのミドルウェア利用時に、
    • ミドルウェアに渡す引数の形式
    • ミドルウェアから返す値(本来はフルのハッシュ) が正しく扱われておらず、結果として「コンテキスト情報の大半が失われる」状態になっていました。

この PR は、そのミドルウェアの使い方を report と同じ契約に揃える修正です。


2-2. ActiveSupport::ErrorReporter の修正

activesupport/lib/active_support/error_reporter.rb の変更は 1 行のみですが、本質的には以下の点を揃えるための修正です。

  • ミドルウェアは report と同じシグネチャ(例: error, handled:, severity:, context: など)を受け取り、
  • report と同様に「情報を含んだハッシュ」を返す必要がある。

もともとミドルウェアの呼び出し側が返り値をうまく扱っておらず、
「ハッシュの一部しか使われない/破棄される」ような状態になっていたため、
ErrorReporter 側の実装・インターフェイスの明示 / 合わせ込みが行われています。

※実際の差分は 1 行ですが、middlewarereport と同じ形で動くことを前提にする意図がはっきりしています。


2-3. Rails::Application ブートストラップでのミドルウェア利用の修正

railties/lib/rails/application/bootstrap.rb で 3 行追加・3 行削除が行われています。

ここが今回のバグの本体で、
Rails がアプリケーション起動時に error_reporter のミドルウェアを組み込む際の呼び出し方が間違っていた ため、コンテキストが欠落していました。

修正内容のポイント:

  • ミドルウェアに渡す引数の形を ErrorReporter#report と同じに合わせる。
  • ミドルウェアからの返り値として「フルのハッシュ(error, handled, severity, context など)」を期待し、そのまま利用するようにする。

疑似コードイメージでいうと、誤っていた例はおおよそこんな感じです:

ruby
# NG なパターン(イメージ)
middleware.call(error, handled: true) # => 実際にはハッシュが返るべきだが、値を無視 or 一部しか使用していない

修正後は「report と同じ契約」に沿ってこう扱う形になります:

ruby
# OK なパターン(イメージ)
result = error_reporter.middleware.call(error, handled: true, severity: :error, context: { ... })
# result はフルのハッシュを返す前提で、そのまま後段に渡される

つまり、「ミドルウェアは report のラッパーであり、API も同じである」という前提にコードを揃えています。


2-4. テストの追加

railties/test/application/app_revision_test.rb に 18 行のテストが追加されています。

テストの目的は、以下のような観点を確認することです:

  • Rails アプリケーション起動(または app revision 関連の処理)の中で error_reporter ミドルウェアが適切に使われているか。
  • エラーが発生したときに、
    • コンテキスト情報を含んだハッシュがミドルウェアから返却される
    • その情報が失われずに処理される ことを保証する。

このテストによって、「以前の誤った使い方に戻ってしまう」回 regresion を防ぐ狙いがあります。


  1. 影響範囲・注意点
  • 影響を受けるのは主に Rails アプリケーションで ActiveSupport::ErrorReporter のミドルウェアフックを利用しているケース です。
    • 例: Sentry / Honeybadger / Bugsnag などのエラーレポートサービスと error_reporter を連携している場合に、
      ミドルウェアレベルで追加コンテキストを付与しているコードなど。
  • この修正により、
    • これまでミドルウェア経由のエラー報告で落ちていたコンテキスト情報(ユーザー情報、リクエスト情報、アプリ独自のメタデータなど)が、正しく報告されるようになります。
  • 互換性面では、
    • 正しい契約(report と同じ引数・返り値)を前提にミドルウェアを実装している場合は、そのまま恩恵を受けるだけ です。
    • 仮に「間違った挙動に依存していた」ミドルウェア実装がある場合は、返り値の扱い等で挙動が変わる可能性がありますが、そのようなケースは稀で、かつもともと非意図的な挙動だったと考えられます。
  • フレームワーク内部のバグ修正に近く、アプリケーションコードの変更が必須になる性質の修正ではありません。

  1. 参考情報 (あれば)
  • この PR は #56490 のフォローアップです。#56490 で導入/変更された error_reporter 関連の処理のうち、「ミドルウェアの使い方」部分にバグがあったため、その修正として位置づけられます。
  • ActiveSupport::ErrorReporter を独自に利用している場合は、
    • ミドルウェアを実装する際に report と同じシグネチャ・返り値(詳細情報を含むハッシュ)を意識する
    • Rails の内部挙動に合わせておく ことで、今回の修正と一貫した動作を得られます。

#56515 remove redundant require for erb

マージ日: 2026/1/5 | 作成者: @yskkin

  1. 概要 (1-2文で)
    Rails アプリケーションの初期化処理から、不要になっていた erbrequire 行を削除した PRです。erb は必要な箇所(ActiveSupport::ConfigurationFile)側で遅延ロードされるようになっているため、重複した読み込みを整理しています。

  1. 変更内容の詳細

変更ファイル:

  • railties/lib/rails/application.rb(1行削除)

実質的な変更は、Rails::Application 定義付近で行われていた次のような記述の削除です:

ruby
# 例: 変更イメージ
# require "erb"  # ← この1行が削除された

PR のモチベーションにある通り、erb は設定ファイルの読み込みを行う ActiveSupport::ConfigurationFile 側で必要に応じて require されるようになっています。

該当コード(AS::ConfigurationFile 側の処理イメージ):

ruby
# activesupport/lib/active_support/configuration_file.rb

def read(path)
  require "erb"      # 必要になった時点でロード
  erb = ERB.new(File.read(path))
  # ...
end

そのため Rails::Application 側でグローバルに require "erb" しておく必要はなく、重複を取り除く形でクリーンアップされています。


  1. 影響範囲・注意点
  • Rails を通常どおり利用している限り、挙動の変化はほぼありません。
    • 設定ファイル (database.yml, credentials.yml.enc を復号した結果の YAML など) の ERB 展開はこれまでどおり行われます。
  • 影響しうるケースは、「アプリ側やプラグイン側が、たまたま rails/application の読み込み経由で erb がすでにロードされていること」に依存していた場合です:
    • 例:
      ruby
      # どこにも require "erb" していないが、
      # Rails を読み込んでいる前提で ERB を使っていたコード
      ERB.new("...")  # ← 以前は 'rails/application' 経由で動いていたかもしれない
    • こうしたコードは、この PR 以降のバージョンでは NameError / LoadError となる可能性があります。
  • 対応策としては、ERB に依存するコード側で明示的に require "erb" を行うのが正しい使い方です:
    ruby
    require "erb"
    
    template = ERB.new("Hello, <%= name %>")
    puts template.result_with_hash(name: "Rails")
  • Rails 本体は ActiveSupport::ConfigurationFile 経由で ERB を利用する設計に一本化されており、その内部で require "erb" を行うため、Rails 自身の機能が壊れることは想定されていません。

  1. 参考情報 (あれば)

#56489 [ci skip] [docs] Mark Exception#as_json as nodoc

マージ日: 2026/1/5 | 作成者: @Yuhi-Sato

  1. 概要 (1-2文で)
    Active Support の core_ext に定義されている Exception#as_json を、公開APIではなく内部実装として扱うためにドキュメントから非公開(:nodoc:)にする変更です。コードの動作には一切影響せず、あくまでドキュメント上の扱いを整理しただけの PR です。

  1. 変更内容の詳細

何をしたか

変更ファイルは 1 つだけです。

  • activesupport/lib/active_support/core_ext/object/json.rb

このファイル内で定義されている Exception 向けの拡張が、これまで通常どおり RDoc/YARD に拾われる状態だったのを、#:nodoc: を付けることで非公開扱いに変更しています。

PR 説明から読み取れる意図をコードイメージにすると、おおよそこんな感じです(実際のコードから簡略化・意訳):

ruby
# 変更前イメージ
class Exception
  def as_json(*)
    # ActiveSupport 独自の JSON エンコード用実装
  end
end

# 変更後イメージ
class Exception #:nodoc:
  def as_json(*)
    # ActiveSupport 独自の JSON エンコード用実装
  end
end

ポイント:

  • Exception#as_json 自体は以前の PR(https://github.com/rails/rails/pull/23702)で導入されており、JSON エンコードの挙動を調整するための内部フックです。
  • このメソッドは ActiveSupport::ToJsonWithActiveSupportEncoder#to_json から内部的に呼び出される実装詳細であり、アプリケーション開発者が直接利用することを想定していません。
  • Object#as_json など、同じような役割の as_json 実装はすでに :nodoc: 指定されており、それと整合させる整理です。
  • as_json が唯一の Exception 拡張であり、Exception の core_ext 自体を公開拡張ポイントにしたくないため、クラスレベルで :nodoc: が付与されています。

  1. 影響範囲・注意点

影響範囲

  • ランタイム挙動への影響はなし

    • 実行時のコードは一切変わっておらず、Exception#as_json の実装もその呼び出し元も従来どおり動きます。
    • テストも追加・変更はなく、純粋にドキュメント生成のためのメタ情報変更です。
  • ドキュメントへの影響

    • Rails の API ドキュメント(api.rubyonrails.org 等)から、Exception の core_ext による as_json 定義が表示されなくなります。
    • これにより、「Rails が公式に保証する公開 API」としては扱われないことが明確になります。

注意点 / 開発者目線での示唆

  • もしアプリケーション側で Exception#as_json に直接依存しているコードがある場合、それは非公開 API への依存という位置づけになります。
    • 将来の Rails バージョンで、予告なく仕様変更・削除される可能性があります。
  • エラーオブジェクトを JSON 化したい場合は、可能な限り以下のように自身でラッピングする方が安全です:
    ruby
    def error_to_hash(error)
      {
        class:   error.class.name,
        message: error.message,
        backtrace: error.backtrace
      }
    end
    
    render json: error_to_hash(e)
  • ライブラリ・Gem 作者の視点では、「Exception#as_json を正式な拡張ポイントとして使わないでね」という Rails チームからのシグナルと捉えるのが妥当です。

  1. 参考情報 (あれば)
  • 当該メソッド導入 PR:
  • 関連する設計方針:
    • as_json 系のメソッドは Active Support の内部エンコード処理と密接であり、互換性維持コストを下げるためにも多くが :nodoc: として扱われています。
  • CI スキップとドキュメントタグ:
    • タイトルの [ci skip] [docs] は、この PR がコードロジックに影響しないドキュメント関連のみであることを示しています。

#56499 [ci skip] Fix typo in railties/CHANGELOG.md, defaults -> default

マージ日: 2026/1/5 | 作成者: @coderhs

  1. 概要 (1-2文で)
    Railties の CHANGELOG.md に記載されていた英語のタイポ「By defaults」を「By default」に修正するドキュメントのみの変更です。コードや挙動には一切影響しない、表記揺れ/誤記の修正 PR です。

  2. 変更内容の詳細(あればサンプルコードも含めて)

  • 対象ファイル: railties/CHANGELOG.md
  • 変更内容: 文章中の「By defaults」を「By default」に修正

具体的には、以下のような 1 行の変更です(イメージ):

diff
- * By defaults, generators will create ...
+ * By default, generators will create ...

CHANGELOG の記述を正しい英語に整えただけであり、API 仕様や機能説明の意味を変えるものではありません。

  1. 影響範囲・注意点
  • 影響範囲:
    • 実行時の挙動・ビルド・テストには一切影響ありません。
    • 変更対象はドキュメント(CHANGELOG)だけです。
  • 注意点:
    • この PR に関連するコード変更は無いため、Rails アプリケーションの更新作業やマイグレーション対応は不要です。
    • CI を走らせていないことを示す [ci skip] タグがタイトルに付いていますが、ドキュメントのみの変更であるため妥当な指定です。
  1. 参考情報 (あれば)
  • PR: https://github.com/rails/rails/pull/56499
  • 該当ファイル: railties/CHANGELOG.md
  • 「By default」は「デフォルトでは〜」という意味の標準的な表現であり、この修正により CHANGELOG の英語として自然な形になっています。

#56514 Fix rescue typo

マージ日: 2026/1/5 | 作成者: @morgoth

  1. 概要 (1-2文で)
    このPRは、actionpack のテストコード内にある rescue 句のタイポ(誤記)を修正したものです。アプリケーション本体の挙動には影響せず、テストの記述を正しくするための微修正です。

  2. 変更内容の詳細(あればサンプルコードも含めて)

  • 変更ファイル: actionpack/test/dispatch/debug_exceptions_test.rb
  • 変更行数: 1行追加・1行削除(実質1行の書き換え)

具体的には、debug_exceptions_test 内で例外処理を行っているテストコードの rescue 句にタイポがあり、それを正しいクラス名(もしくは適切な例外指定)に修正しています。

イメージとしては、以下のような変更です(※擬似例・実際のクラス名はPR本文参照):

ruby
# 修正前(誤ったクラスや名前)
assert_nothing_raised do
  # ...
rescue DebugExeptions # ← タイポ
  flunk "Should not raise"
end

# 修正後(正しいクラスや名前)
assert_nothing_raised do
  # ...
rescue DebugExceptions # ← 正しい綴りに修正
  flunk "Should not raise"
end

もしくは、Rails のテストでよくあるパターンとして、意図しない例外を拾ってテストを失敗させるための rescue 句で、例外クラス名・モジュール名の綴りが間違っていたものを修正している、という性質の変更です。

このPRには [ci skip] が付いているため、CI は明示的には実行されていませんが、テスト補助コードの単純修正であることから、安全な変更と判断されていると考えられます。

  1. 影響範囲・注意点
  • 影響範囲:
    • Rails の テストコード (actionpack/test/dispatch/debug_exceptions_test.rb) のみ に限定。
    • ランタイムの挙動や、本番アプリケーションの動作には影響しません。
    • ActionDispatch::DebugExceptions まわりのテストが、意図した例外クラスを正しく捕捉できるようになります。
  • 注意点:
    • 自前で Rails のテストスイートを流している場合、これ以前のバージョンでは「本来想定していた例外が rescue されない」「逆に rescue が効いていない」などのテストの不安定要因があった可能性があります。
    • CI を厳密に見ているプロジェクトでは、テストの期待動作がより正しくなることで、将来の変更でテストが新たに落ちる可能性はあります(=今まで取りこぼしていた失敗が顕在化する可能性)。ただし今回のPR単体では新たな不具合を生み出す性質のものではありません。
  1. 参考情報 (あれば)
  • 該当ファイル:
    actionpack/test/dispatch/debug_exceptions_test.rb
    • ActionDispatch::DebugExceptions の挙動(スタックトレース・エラーページ表示・例外ラッピングなど)を検証するテスト群。
  • 関連コンポーネント:
    • ActionDispatch::DebugExceptions(開発・テスト用のエラーハンドリングミドルウェア)
  • 本PRは純粋にタイポ修正であり、仕様変更や公開APIの振る舞い変更は伴っていません。

#56513 Attempt to fix secret_key_base test failure

マージ日: 2026/1/4 | 作成者: @byroot

  1. 概要 (1-2文で)
    テスト環境でごくまれに発生していた「secret_key_base が空文字列になる」フレakyテストを抑止するため、Rails::Application::Configurationsecret_key_base まわりの扱いを調整したPRです。secret_key_base が不正な状態(空文字列など)で使われないよう、防御的なロジックを追加・整理しています。

  1. 変更内容の詳細

※PR本文とスタックトレースから読み取れる範囲での解説です。実際のdiffは概ね以下のような性質の変更になります。

問題の状況

テストで以下のようなエラーが時々発生していました:

text
ArgumentError: `secret_key_base` for test environment must be a type of String, got: ""`
    lib/rails/application/configuration.rb:563:in 'Rails::Application::Configuration#secret_key_base='
    lib/rails/application/configuration.rb:547:in 'Rails::Application::Configuration#secret_key_base'
    lib/rails/application.rb:511:in 'Rails::Application#secret_key_base'
    lib/rails/application.rb:328:in 'Rails::Application#env_config'
  • 期待されるのは「String かつ有効な secret_key_base
  • 実際には ""(空文字)が渡ってきており、それをはじくチェックで ArgumentError が出ている
  • しかもフレaky(ときどきしか再現しない)ため、設定の初期化タイミングやキャッシュ/メモ化まわりで競合や順序依存が発生している可能性がある

変更の方向性

railties/lib/rails/application/configuration.rb に対して、主に以下のような修正が入っています:

  1. secret_key_base のゲッター/セッターのロジック強化

    • セッター側で「nil や空文字列をそのまま保持しない」ようにする、あるいは
    • 空文字列が渡された場合は「未設定」と同等に扱うか、もしくはその時点でより分かりやすいエラーを出す、などの防御的実装に変更
    • 既存の「型チェック」に加え、「値の妥当性(空文字禁止など)」の扱いを整理
  2. 内部的なデフォルト値・メモ化の扱いを調整

    • secret_key_base を参照する際に、どのソース(credentials, ENV["SECRET_KEY_BASE"], 生成されたダミーキーなど)から引くかの順序の見直し
    • 途中で空文字が混入しないように、presence チェックや条件分岐を追加
    • 一度解決した secret_key_base をメモ化する際、「不正な値をキャッシュしない」ようにする
  3. テストで発生しているパターンへのピンポイント対策

    • PRタイトルに「Attempt to fix」とあるため、「根本原因が完全特定できていないが、起こり得る経路を潰す」ための変更が入っている可能性が高いです。
    • たとえば、以下のようなコードに近い変更が入り得ます(イメージ):
    ruby
    def secret_key_base=(value)
      if value.nil? || value == ""
        @secret_key_base = nil
        return
      end
    
      unless value.is_a?(String)
        raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String, got: #{value.inspect}`"
      end
    
      @secret_key_base = value
    end
    
    def secret_key_base
      return @secret_key_base if defined?(@secret_key_base) && @secret_key_base.present?
    
      # ここで credentials や ENV などから安全に解決するロジックを実行
      @secret_key_base = resolve_secret_key_base_from_sources
    end

    実際のコードとは細部が異なり得ますが、「空文字が確定的に使われないようにする」方向の修正です。


  1. 影響範囲・注意点
  • 対象: Rails アプリ全般の secret_key_base 解決ロジック

    • railtiesRails::Application::Configuration が変更されるため、全Railsアプリの secret_key_base の決定ロジックに影響します。
    • ただし、正しく secret_key_base を設定しているアプリ(config/credentials.yml.enc, ENV["SECRET_KEY_BASE"] など)には実質的な挙動変更はほぼないはずです。
  • 空文字列や不正値を設定している環境への影響

    • これまで「たまたま動いていた」ような設定(例: SECRET_KEY_BASE="" が入っている)では、
      • より早い段階でエラーが出る
      • もしくは Rails 側で自動生成のダミーキーに切り替えられる
        といった挙動に変わる可能性があります。
    • 本番環境では secret_key_base がセッション暗号や署名に直結するため、必ず明示的かつ非空の String を設定しているか確認した方が安全です。
  • テスト環境での安定性向上

    • PRの主目的はテストのフレakyさ解消なので、Rails本体やアプリケーションのテスト実行時に、ランダムに落ちるケースが減ることが期待されます。
    • もしこれまで secret_key_base 関連でランダムな失敗を見ていた場合、このPRを含むRailsバージョンへアップデートすることで改善する可能性があります。

  1. 参考情報 (あれば)
  • 該当クラス:
    • railties/lib/rails/application/configuration.rb
      Rails::Application::Configuration#secret_key_base / #secret_key_base=
  • 関連ドキュメント:
    • Railsガイド: セキュリティ / secret_key_base
      https://guides.rubyonrails.org/security.html#sessions
    • config.secret_key_base の設定方法:
      • config/credentials.yml.enc (rails credentials:edit)
      • 環境変数 SECRET_KEY_BASE
      • config/initializers/secret_token.rb(古いアプリ)

このPRの本質は「secret_key_base 決定ロジックの防御性を高め、空文字列など不正な状態を早期かつ安定的に検出・排除する」ことです。


#56506 Deprecate delayed_job Active Job adapter

マージ日: 2026/1/4 | 作成者: @morgoth

  1. 概要 (1–2文で)
    Rails の Active Job における delayed_job アダプタが非推奨 (deprecate) としてマークされました。今後のバージョンで削除される可能性があるため、他のキューイングバックエンドへの移行が推奨されます。

  1. 変更内容の詳細

このPRでは 2 点のみが変更されています。

a. CHANGELOG への追記

activejob/CHANGELOG.md に、delayed_job アダプタが非推奨になった旨が追記されています。
(次のメジャー/マイナーバージョンでの扱い・削除予定が明記されている可能性があります。)

b. アダプタ本体への deprecation 警告追加

activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb に、利用時に deprecation 警告を出すロジックが追加されています。典型的には以下のような形です(実際のメッセージ内容は概ねこのイメージ):

ruby
module ActiveJob
  module QueueAdapters
    class DelayedJobAdapter
      def initialize(*)
        ActiveSupport::Deprecation.warn(
          "The delayed_job Active Job adapter is deprecated and will be removed in a future Rails version. " \
          "Please migrate to another queue adapter (e.g. :sidekiq, :resque, :good_job, :solid_queue, etc.)."
        )
        super
      end

      # 既存の実装は基本的にそのまま
    end
  end
end

あるいは、クラス定義直下などで一度だけ警告を出す実装になっている可能性もありますが、いずれにせよ:

ruby
config.active_job.queue_adapter = :delayed_job

を設定していると、アプリケーション起動時やジョブ実行時に「delayed_job アダプタは非推奨です」という警告がログに出るようになります。


  1. 影響範囲・注意点

影響範囲

  • 対象: config.active_job.queue_adapter = :delayed_job を利用している Rails アプリケーション
  • 影響内容:
    • Rails 実行時に ActiveSupport::Deprecation による警告ログが出力されるようになります。
    • すぐに壊れるわけではありませんが、「将来の Rails バージョンで削除される予定」であることが明示されました。

注意点・推奨アクション

  1. 今後も Active Job を使う場合は移行先を検討すること
    代表的な移行先:

    • :sidekiq
    • :resque
    • :good_job
    • :solid_queue(Rails 7.1+ / 8 以降での標準寄りの選択肢)

    例: Sidekiq に移行する場合

    ruby
    # Gemfile
    gem "sidekiq"
    
    # config/application.rb (もしくはそれぞれの環境設定)
    config.active_job.queue_adapter = :sidekiq
  2. delayed_job 自体の今後のメンテ状況に注意
    このPRは collectiveidea/delayed_job 本体のPR (https://github.com/collectiveidea/delayed_job/pull/1236) を受けての追随です。

    • delayed_job 側でも Active Job 連携まわりが非推奨・互換性縮小の流れにある可能性があります。
    • 既存アプリで delayed_job を使い続ける場合、Active Job を経由せずに直接 delayed_job の API を使う設計に切り替える、という選択肢もありますが、長期的には別のジョブキューへの移行を検討した方が安全です。
  3. CI で deprecation をエラー扱いしている場合

    • ActiveSupport::Deprecation.behavior = :raise のように設定している環境では、この変更によりテストが落ちる可能性があります。
    • 一時的に delayed_job アダプタの警告だけを無視するか、アダプタ移行を優先的に行う必要があります。

  1. 参考情報 (あれば)

これらを踏まえると、「Rails プロジェクトで delayed_job を Active Job と組み合わせて使い続ける」のは中長期的には非推奨となり、今のうちに別アダプタへの移行計画を立てるべき段階に入ったと考えておくのがよいです。


#56509 Update mandrill's document URL in Action Mailbox basics [ci skip]

マージ日: 2026/1/4 | 作成者: @unasuke

  1. 概要 (1-2文で)
    Action Mailbox ガイド内で参照していた Mandrill(Mailchimp Transactional)の受信メール処理ドキュメントURLが、現行の公式ドキュメントURLに差し替えられたPRです。内容としてはドキュメント中のリンク1箇所のみを更新する、極めて小さな変更です。

  1. 変更内容の詳細(あればサンプルコードも含めて)
  • 対象ファイル:

    • guides/source/action_mailbox_basics.md
  • 変更内容:
    Action Mailbox の「Mandrill を使った受信メール処理」に関する説明部分で、Mandrill の公式ドキュメントへのリンクURLが更新されています。

    旧URL(既に公式サイトから削除済み):

    • https://mandrill.zendesk.com/hc/en-us/articles/205583197-Inbound-Email-Processing-Overview

    新URL(Mailchimp の現行ドキュメント):

    • https://mailchimp.com/developer/transactional/guides/set-up-inbound-email-processing/

    実際の変更は Markdown 上で上記URLが単純に置き換えられただけ(+1/-1行)で、ガイド文章の内容やコード例には変更がありません。

  • 著者コメントによる補足:

    • 旧URLは削除されており、Web Archive(2019年のスナップショット)の内容と、新URLの内容が実質的に同等であることを確認した上で置き換えています。

  1. 影響範囲・注意点
  • 影響範囲:

    • Rails ガイド(Action Mailbox Basics)を閲覧する開発者向けドキュメントにのみ影響します。
    • アプリケーションコード、Rails 本体の機能、挙動、API 仕様には一切影響しません。
    • テストや CHANGELOG の更新は不要な種類の変更(ドキュメントのみ)であり、その通りになっています。
  • 注意点:

    • Mandrill は現在「Mailchimp Transactional Email」として提供されているため、今後もリンク切れやURL構成変更が起こり得ます。
      ドキュメントを自プロジェクト内で引用している場合は、新URLに追随しておくとよいでしょう。
    • Rails の Action Mailbox で Mandrill/Mailchimp Transactional を使って inbound を処理している場合、このリンク先の手順は公式の最新ガイドラインとして参照できますが、Rails 側のセットアップ手順(routes, ingress, ActionMailbox::Ingresses::Mandrill 等)は Rails ガイド側を引き続き参照する必要があります。

  1. 参考情報 (あれば)

#56512 Remove minitest-ci

マージ日: 2026/1/4 | 作成者: @byroot

  1. 概要 (1-2文で)
    Rails のテスト用に導入されていた minitest-ci が、長らく壊れたまま使われていなかったため、依存関係と設定ごと削除されました。これにより Ruby 4.0 実行時に出ていた CGI に関する警告も解消されます。

  1. 変更内容の詳細

この PR では、minitest-ci に関する設定・依存がすべて削除されています。

  • Gemfile

    • minitest-ci の gem 依存が 1 行削除されています。
  • Gemfile.lock

    • minitest-ci 関連のエントリが 3 行削除されています。
    • これにより、bundle インストール時に minitest-ci は引き込まれなくなります。
  • tools/test_common.rb

    • テスト共通設定から minitest-ci を利用するためのコードが削除されています(4 行削除)。
    • 典型的には以下のようなコードが削除対象と推測されます(あくまでイメージ):
      ruby
      # require "minitest/ci"
      # Minitest::Ci.report_dir = ENV["CI_REPORTS"] if ENV["CI_REPORTS"]
    • これにより、minitest-ci を前提としたレポート出力などは行われなくなります。

元々 minitest-ci は、過去の PR (https://github.com/rails/rails/pull/35698) で「テスト失敗の自動解析などを行うため」に導入されたものですが、長期間動作が壊れた状態で実質的に使われていなかったため、今回の PR でクリーンアップされています。


  1. 影響範囲・注意点
  • Rails 本体のテスト:

    • Rails コアリポジトリで bundle exec ruby -w などを使ってテストを実行した際に発生していた、Ruby 4.0 における CGI 関連の warning が解消されます。
    • minitest-ci を前提とした CI レポート生成は行われなくなりますが、そもそも壊れて機能していなかったため、実務上の挙動はほぼ変わりません。
  • Rails を利用するアプリケーション側:

    • アプリケーションの Gemfileminitest-ci を入れている場合には、この PR による直接の影響はありません(Rails 本体の開発用設定の削除にとどまるため)。
    • ただし、「Rails 本体が minitest-ci を使っているのだから自分たちも同じ前提で…」というような暗黙の前提に依存している場合は見直しが必要になる可能性があります。
  • 将来的な再導入:

    • 説明文にもある通り、誰かが minitest-ci を修正して再度利用可能にしたい場合は、将来的に再導入される余地が残されています。
    • 現時点では「壊れた機能を残すより、一度きれいに削除する」という判断です。

  1. 参考情報 (あれば)

#56511 Drop support for Ruby 3.2

マージ日: 2026/1/4 | 作成者: @byroot

  1. 概要 (1-2文で)
    Rails 8.2 以降で Ruby 3.2 のサポートを正式に打ち切る PR で、サポート対象 Ruby バージョンの下限が 3.3 以上に引き上げられています。Ruby 3.2 固有のコードは存在しないため、実質的には「対応バージョン宣言」と CI 対象からの除外のみです。

  1. 変更内容の詳細

ポリシー面の変更

PR 説明から分かるポイント:

  • Rails のサポートポリシー:
    • 「新しい Rails のマイナーバージョンをリリースする時点で、Ruby 側が EOL (End of Life) になっていないバージョンのみをサポートする」
  • Ruby 3.2 は 2026-04-01 に EOL になる予定
  • Rails 8.2 をリリースする頃には Ruby 3.2 はすでに EOL になっている想定
  • そのため、Rails 側としても 3.2 をサポート対象から外す、という判断

コード上の変更点

変更ファイルはほぼすべて .gemspec とドキュメントです:

  • 各コンポーネントの gemspec:
    • actioncable/actioncable.gemspec
    • actionmailbox/actionmailbox.gemspec
    • actionmailer/actionmailer.gemspec
    • actionpack/actionpack.gemspec
    • actiontext/actiontext.gemspec
    • actionview/actionview.gemspec
    • activejob/activejob.gemspec
    • activemodel/activemodel.gemspec
    • activerecord/activerecord.gemspec
    • activestorage/activestorage.gemspec
    • activesupport/activesupport.gemspec
    • rails.gemspec
    • railties/railties.gemspec
    • tools/rail_inspector/rail_inspector.gemspec
    • tools/releaser/releaser.gemspec
  • ドキュメント:
    • guides/source/getting_started.md

これらのファイルで行われている変更は、基本的に「対応 Ruby バージョンの下限を 3.3 に上げる」だけです。

代表例 (イメージ):

ruby
# 変更前 (例)
spec.required_ruby_version = ">= 3.2.0"

# 変更後 (例)
spec.required_ruby_version = ">= 3.3.0"

guides/source/getting_started.md でも、推奨あるいは必須 Ruby バージョンの記述が 3.2 → 3.3 に更新されています。

PR 本文にもあるとおり:

We don't have any Ruby 3.2 specific codepath that I could find, so this does allow any cleanup.

Ruby 3.2 特有の分岐や互換レイヤーはそもそも存在していないため、条件分岐削除などの「コードの掃除」は一切行われていません。あくまで「サポート対象の宣言と CI 対象の更新」のみです。


  1. 影響範囲・注意点

影響を受けるケース

  • Rails 8.2 (およびこの PR が入ったブランチ以降) を使おうとしているのに、アプリケーションの本番/開発環境が Ruby 3.2 のまま:
    • Bundler によってインストール時に弾かれる可能性が高いです。
    • 実行できたとしても「未サポートの Ruby で動かしている」状態になるため、バグ報告やサポートの対象外とみなされます。

対応が必要な開発者

  • Rails 8 系へのアップグレードを検討しているプロジェクト:
    • Ruby 3.3 以上へのアップグレードを前提に計画を立てる必要があります。
  • 現在 Ruby 3.2 を使っていて、しばらくバージョンを上げられない事情がある場合:
    • Rails 8.1 以前に留まる、もしくは Ruby のアップグレード計画を立てる必要があります。

実行時の互換性について

  • コード上に Ruby 3.2 専用分岐がないため、「Ruby 3.2 で動かなくなるような即時の互換性破壊変更」はこの PR 単体では入っていません。
  • ただし:
    • 今後の PR で Ruby 3.3 以降を前提とした構文・標準ライブラリ機能が自由に使われる可能性が高く、結果として Ruby 3.2 では動かなくなることが想定されます。
    • 公式としては「動作保証外」であるため、不具合が出ても修正されない前提で考えるべきです。

  1. 参考情報 (あれば)

#56510 Update gems incompatible with Ruby 4.0

マージ日: 2026/1/4 | 作成者: @byroot

  1. 概要 (1-2文で)
    このPRは、Ruby 4.0 で bundle install を実行した際に互換性問題を起こす gem をアップデートし、Rails リポジトリ全体が Ruby 4.0 でもバンドル・ビルドできるようにしたものです。併せて、tools/strict_warnings.rb に最小限の追記が行われています。

  1. 変更内容の詳細

Gemfile.lock の更新

  • 目的: Ruby 4.0 でインストール・テストが通るように、非互換な gem のバージョンを上げる(あるいは依存関係の解決を更新)ための Gemfile.lock 更新です。
  • 実施内容:
    • Gemfile.lock で複数の gem のバージョンが上がっています(+11/-27 行という差分から、古いエントリの削除と新バージョンへの置き換えが中心)。
    • 典型的には以下のような変更が行われていると考えられます:
      • Ruby 4.0 で廃止・非推奨になった API を使っていた gem の新バージョンへのアップデート
      • Ruby のバージョン制約 (ruby '>= 3.0' など) が Ruby 4.0 を許容するようになったバージョンへの更新
      • 依存ツリー全体を再解決した結果としてのバージョン揃え

実ファイルでは、例えば以下のような差分が想定されます(あくまでイメージです):

diff
- foo (1.2.3)
-   ruby_dep (~> 3.2)
+ foo (1.3.0)
+   ruby_dep (>= 3.2)

「Ruby 4.0 非対応」な gem は、しばしば required_ruby_version の上限や、内部で使っている Ruby のメソッド仕様変更によってエラーになるため、PR の目的はそれらをまとめて「Ruby 4.0 対応版」に揃えることです。

tools/strict_warnings.rb の変更

  • このファイルは、Ruby の警告を厳しめに扱うためのスクリプト(テストや CI で -W:2 相当の扱いなど)を行う補助ツールであることが多いです。

  • 今回の差分は +1 行のみで、以下のような変更が想定されます:

    • Ruby 4.0 での警告クラス・警告レベルの変更への追従
    • Ruby バージョンを判定して挙動を切り替える条件の追加
    • Ruby 4.0 で追加・変更されたオプションや定数の取り扱い

例としては、次のようなガードが追加されるケースがあります(例・擬似コード):

ruby
if RUBY_VERSION >= "4.0"
  Warning[:deprecated] = true
end

実際のコードは異なる可能性がありますが、趣旨としては「Ruby 4.0 で警告設定まわりが壊れないようにする小さな修正」です。


  1. 影響範囲・注意点
  • Rails 本体の開発者・コントリビュータ

    • この PR により、Ruby 4.0 で bundle install が通り、テストや開発が進めやすくなります。
    • 手元で Ruby 4.0 を使う場合は、この PR 以降の Gemfile.lock に合わせて bundle install することで、互換性の取れた gem セットを利用できます。
    • gem のバージョンが複数まとめて上がっている可能性があるため、Ruby 4.0 だけでなく Ruby 3.1〜3.3 など既存開発で使われているバージョンでもテストを回し、想定外の挙動変更(パフォーマンス、警告の出方、依存 gem の API 変更など)がないか確認するのが望ましいです。
  • Rails を利用するアプリケーション側への直接の影響

    • これは Rails 本体リポジトリの Gemfile.lock 更新であり、一般的な Rails アプリの Gemfile.lock には直接は影響しません。
    • ただし、「Rails 本体が Ruby 4.0 用にこういった gem 更新をしている」というのは、将来的にアプリ側でも Ruby 4.0 対応を行う際の参考になります。
    • アプリで Ruby 4.0 に上げる予定がある場合、同様に bundle update を行って、Ruby 4.0 対応版に揃える必要があります。
  • CI / 警告ハンドリングまわり

    • tools/strict_warnings.rb の変更により、Ruby 4.0 でテスト実行時の警告扱いが変わる可能性があります。
    • これまで無視されていた警告が落ちるようになったり、逆に Ruby 4.0 でクラッシュしていたものが正常動作するようになっている可能性があります。
    • 新たに発生する警告やエラーがないか、Ruby 4.0 環境での CI 実行ログを確認するのが安全です。

  1. 参考情報 (あれば)
  • Ruby 4.0 向けの互換性情報(まだ正式リリース前であれば preview/beta リリースノート)
    • Ruby 3.3 以降の変更点や deprecation も Ruby 4.0 の下地になっているため、以下を参考にするとどの API が影響しそうか把握できます。
      • Ruby 3.3 / 3.2 / 3.1 の NEWS, Changelog
  • Rails コントリビュートガイドライン
    • Ruby のサポートバージョンとテストマトリックス: 各 Ruby バージョンで CI を回しているため、Ruby 4.0 対応が進むにつれて、同様の gem 更新 PR が増える可能性があります。
  • Gem 側の対応状況
    • 個々の gem の CHANGELOGgemspecrequired_ruby_version フィールドを確認すると、「どのバージョンから Ruby 4.0 をサポートしているか」が分かり、アプリ側での更新時にも参考になります。

#56476 Add LeakChecker to tools and fail on ENV leaks

マージ日: 2026/1/4 | 作成者: @zzak

  1. 概要 (1-2文で)
    Rails のテストスイートに「環境変数のリーク検出」を行う LeakChecker ツールが追加され、テスト実行中に汚染された ENV があれば失敗させる仕組みが導入されました。あわせて、既存テストで検出された ENV リークも修正されています。

  1. 変更内容の詳細

2-1. LeakChecker ツールの追加

tools/support/leak_checker.rb が新規追加され、Ruby 本体の tool/lib/leakchecker.rb に着想を得た「簡易 ENV リーク検出ツール」が導入されています。

典型的な構成は次のような形です(擬似コードイメージ):

ruby
module Tools
  class LeakChecker
    def initialize
      @initial_env = ENV.to_hash.freeze
    end

    def check!
      current = ENV.to_hash
      added   = current.keys - @initial_env.keys
      changed = current.keys & @initial_env.keys
      changed.select! { |k| current[k] != @initial_env[k] }

      if added.any? || changed.any?
        # ここでテストを fail させる / レポートを出す
        raise "ENV leaked: added=#{added.inspect}, changed=#{changed.inspect}"
      end
    end
  end
end

実際のコードでは、

  • 「どのキーの ENV が増えたか」
  • 「どのキーの値が変化したか」
    を記録し、テスト終了後に差分があれば失敗扱いにするような動作になっています。

2-2. test_common への統合

tools/test_common.rb に LeakChecker を組み込む処理が追加されています。

ここで行っていることは概ね以下のような流れです:

  1. テストスイート開始前に LeakChecker を初期化し、初期状態の ENV をスナップショット。
  2. テストスイート終了時(あるいは特定のテストグループ終了時)に LeakChecker.check! を呼び出し、初期状態と比較。
  3. 差分があればテスト失敗として扱う。

これにより、「テストが ENV を書き換えたまま元に戻していない」 という問題を CI 上で検出できるようになります。

2-3. 既存テストコードの修正

LeakChecker 導入に伴い、実際に ENV を汚染していたテストが修正されています。

actionview/lib/action_view/test_case.rb

diff
- # 何らかの ENV 操作をしてそのまま…という形だったものが、
+ # ENV を変更する前に退避し、ensure で戻すようなパターンに修正
  setup do
-  ENV["SOME_ENV"] = "value"
+  @original_some_env = ENV["SOME_ENV"]
+  ENV["SOME_ENV"] = "value"
  end

  teardown do
+  ENV["SOME_ENV"] = @original_some_env
  end

のように、「テストの setUp で ENV をいじる → tearDown で必ず戻す」という形に統一されています。(実際のキー名や用途はファイルに依存しますが、パターンとしてはこの形。)

railties/test/isolation/abstract_unit.rb

isolation 系テストはプロセス分離や環境の切り替えを多用するため、ENV を変更しがちです。ここでも:

  • ENV["RAILS_ENV"]SECRET_KEY_BASE 周りの値設定
  • テスト後に元の値へ確実に戻す

といった修正が入っており、プロセス間・テスト間での副作用を抑えるようになっています。

その他テストファイル

  • railties/test/application/zeitwerk_checker_test.rb
  • railties/test/isolation/test_helpers_test.rb

にも 1 行ずつ追加されており、こちらも LeakChecker を意識した ENV の初期化/クリーンアップの調整が行われています。


  1. 影響範囲・注意点

影響範囲

  • Rails 本体のテストスイート実行時
    • ENV を書き換えて元に戻していないテストは、今後 CI / ローカルで失敗するようになります。
  • Railties / ActionView のテスト
    • 特に isolation テストや、rails_info_controller_test 周辺など、SECRET_KEY_BASE などの設定に絡むテストで影響が出る可能性があります。

開発者が気をつけるべき点

  1. テストで ENV を触るときは、必ず退避&復元する

    ruby
    around do |test|
      old = ENV.to_hash
      begin
        ENV["FOO"] = "bar"
        test.call
      ensure
        ENV.replace(old)
      end
    end

    あるいは、必要なキーだけ個別に退避・復元しても構いません。

  2. 並列実行・共有プロセスでの ENV 変更は特に注意

    • 並列テストや isolation が絡むケースでは、ENV の書き換えが他テストに波及しやすいため、LeakChecker によって不安定なテストを早期にあぶり出せます。
  3. SECRET_KEY_BASE / SECRET_KEY_BASE_DUMMY まわり

    • 今回の発端が secret_key_base 関連の flakey test であるため、この辺りの ENV や設定値をテスト中に変える場合は、特に確実に元に戻す必要があります。
    • テスト固有の SECRET_KEY_BASE を使う場合は「テストの間だけ上書き」するラッパ (helper) を導入するのが安全です。

  1. 参考情報 (あれば)

#56500 Fix detected LeakChecker ENV leaks

マージ日: 2026/1/4 | 作成者: @zzak

  1. 概要 (1-2文で)
    このPRは、Rails のテストにおいて ENV の変更がテスト間でリークしている問題を、LeakChecker に検知されないように修正したものです。主にテストコード内での環境変数の扱い方を見直し、「設定したら必ず元に戻す」形に統一しています。

  1. 変更内容の詳細

※PR #56476 に依存しており、そこですでに導入された LeakChecker(テスト中の ENV 汚染を検出する仕組み)を前提にした修正です。

大きな方針は以下です。

  • テストで ENV を変更する場合は、必ず元の値を復元する
  • 一時的な変更は ensure や専用ヘルパーで巻き取る
  • グローバルに影響する ENV の操作を減らし、局所的に閉じ込める

以下、ファイルごとの方向性の解説です(実際の行単位のコードは省き、パターンを説明します)。

railties/test/application/configuration_test.rb

  • ENV["SOME_VAR"] = "value" のような素の代入を削減し、
    • 事前に old = ENV["SOME_VAR"] を保存
    • ensure 節で ENV["SOME_VAR"] = old に戻す
  • あるいは ENV.delete("SOME_VAR") と組み合わせながら、テスト終了時に必ず元の状態に戻すように変更。

パターン例(イメージ):

ruby
old = ENV["RAILS_ENV"]
ENV["RAILS_ENV"] = "production"
begin
  # テスト本体
ensure
  ENV["RAILS_ENV"] = old
end

railties/test/application/initializers/frameworks_test.rb

  • フレームワーク有効/無効を環境変数で切り替えるテストで、
    • 直接 ENV["DISABLE_ACTIVE_RECORD"] = "1" などとしていた箇所を、
    • テストのスコープ内で変更・復元するように整理。
  • 複数テストケースで同じ環境変数をいじる箇所を共通化し、毎回安全に復元されるようにした可能性が高いです。

イメージ:

ruby
def with_env(name, value)
  old = ENV[name]
  ENV[name] = value
  yield
ensure
  ENV[name] = old
end

def test_active_record_can_be_disabled
  with_env("DISABLE_ACTIVE_RECORD", "1") do
    # テスト
  end
end

railties/test/application/rake/dbs_schema_test.rb

  • Rake タスク (db:schema:* 系) をテストする際に、
    • ENV["SCHEMA_FORMAT"]ENV["DATABASE_URL"] 等を変更していた部分を、
    • テストごとにローカルに管理して、テスト後に元に戻すように変更。
  • 複数の schema 関連テストで同じ環境変数を共有しないようにし、テスト実行順序に依存しない形に。

railties/test/application/rake/dbs_test.rb

  • このファイルの差分が比較的大きく、DB 関連の Rake タスクテストにおける環境変数操作を大きく整理しています。
  • 典型的には以下のような変更が入っている可能性があります。
    • グローバルな ENV["DATABASE_URL"] = ... をやめる
    • with_env のようなテストヘルパー経由で一時的に切り替える
    • テスト中に ENV を書き換える必要がない部分を、引数や設定オブジェクト経由に変更

Rake タスク実行の一例(イメージ):

ruby
with_env("RAILS_ENV", "test") do
  run_task "db:migrate"
end

こうすることで、LeakChecker から見ても「テスト終了時には ENV が元に戻っている」状態になります。

railties/test/application/sprockets_assets_test.rb

  • アセットパイプライン (Sprockets) のテストで、
    • ENV["RAILS_ENV"], ENV["SECRET_KEY_BASE"] 等、環境変数を利用していた箇所を安全なパターンに変更。
  • アセットのプリコンパイルや読み込みで、環境変数に依存している場合でも、テスト中だけ上書きし、必ず復元。

railties/test/generators/action_text_install_generator_test.rb

  • Action Text のインストールジェネレータテストで、
    • 1 行だけの微修正(ENV の扱いの統一、あるいは ENV アクセスの削減)。
  • たとえばジェネレータの実行時に RAILS_ENV を上書きしていたコードを、ヘルパー経由に変えた等の小さな修正が考えられます。

railties/test/generators/generators_test_helper.rb

  • ここはテストヘルパーのファイルで、-3 行のみの削除。
  • 以前存在していた雑な ENV 操作(もしくは不要になったメソッド)を削ったか、
  • より安全な ENV ヘルパーに置き換えた結果、古いヘルパーが不要になったと考えられます。

  1. 影響範囲・注意点
  • 影響範囲は テストコード(railties 配下)限定 で、本番アプリケーションの挙動には影響しません。

  • ただし、以下の点は開発者にとって有益です:

    • 自前のテストでも同様のパターンを採用すべき
      Rails 本体テストが ENV を「必ず元に戻す」スタイルに揃えられたことは、
      アプリ/エンジン/ライブラリ側のテストでも推奨されるパターンであると解釈できます。
    • テストの順序依存バグを防げる
      ENV 汚染がなくなることで、「単体で実行すると通るのに、全体で流すと落ちる」タイプのフレークテストを減らせます。
    • LeakChecker 環境でのテスト実行
      将来的に Rails 本体と同様の LeakChecker(ENV 汚染・定数汚染検出)を導入した場合、
      このPRのスタイルを真似しておけば、検出エラーを避けられます。
  • 自分のテストで ENV をいじっている場合は、次のようなヘルパー導入が有用です:

ruby
def with_env(hash)
  old = {}
  hash.each do |k, v|
    old[k] = ENV[k]
    ENV[k] = v
  end
  yield
ensure
  old.each { |k, v| ENV[k] = v }
end

  1. 参考情報 (あれば)

#56471 Override inspect in Combined, Env & Encrypted Configurations

マージ日: 2026/1/3 | 作成者: @siaw23

  1. 概要 (1-2文で)
    Rails の CombinedConfiguration, EnvConfiguration, EncryptedConfigurationinspect 出力から、実際のシークレット値や ENV の中身を隠し、キー名だけが見えるようにした変更です。コンソール・ログ・エラーレポート等で機密情報が漏洩するリスクを減らすセキュリティ改善です。

  1. 変更内容の詳細

何が問題だったか

従来は以下のように、inspect が内部状態をそのまま表示していました:

ruby
Rails.app.creds
#<ActiveSupport::CombinedConfiguration:0x0000000122b45870
 @configurations=[
   #<ActiveSupport::EnvConfiguration:0x0000000122b465b8
    @envs={"SOME_SECRET" => "secret_value", "DATABASE_URL" => "postgresql://user:pass@host/db", ...}>,
   #<ActiveSupport::EncryptedConfiguration:0x00000000007af0>
 ]
>

ここでは:

  • ENV の値 (DATABASE_URL のユーザ名・パスワードなど)
  • 各種クレデンシャル (SOME_SECRET など)
  • その他内部状態

が丸見えになっており、以下のようなシチュエーションで機密情報が簡単に漏れる危険がありました。

  • Rails コンソールでオブジェクトをうっかり p した / 例外から inspect に巻き込まれた
  • ログにオブジェクトをそのまま出力した
  • エラーレポートや APM が inspect を呼び出して情報を集めた

どう変わったか

この PR では、3つのクラスで inspect をオーバーライドし、値ではなくキーだけを表示するようにしています。

CombinedConfiguration

ruby
Rails.app.creds
#<ActiveSupport::CombinedConfiguration:0x00000000006490
  keys=[:rails_env, :some_secret, ..., :secret_key_base, :stripe_webhook_secret]>

ポイント:

  • 元々は @configurations 配列(EnvConfiguration, EncryptedConfigurationなど)の生の内容が出ていた
  • 今は keys=[...] だけを出す
  • 各キーは シンボル として表示される (:some_secret など)

EncryptedConfiguration

ruby
Rails.app.credentials
#<ActiveSupport::EncryptedConfiguration:0x00000000008cd0
  keys=[:secret_key_base, :stripe_webhook_secret]>

ポイント:

  • これまでは内部構造や値が inspect から見えていた
  • 変更後は復号後の キー名のみ をシンボルで表示
  • コード上のアクセス方法 (config.some_secret) と自然に対応する形

EnvConfiguration

ruby
Rails.app.envs
#<ActiveSupport::EnvConfiguration:0x0000000000a6a0
  keys=[:rails_env, :some_secret, :path, :home, ...]>

ポイント:

  • これまでは @envs={ "KEY" => "VALUE", ... } のように生の ENV 内容が出ていた
  • 今は ENV のキーだけを keys=[...] として表示
  • ENV のキーは本来文字列ですが、inspect 上ではシンボル化して見せることで API と整合性をとっている(他2つと同様)

実装レベルの変更点(想定される形)

コード自体は省略されていますが、概ね以下のイメージです:

ruby
# 例: EncryptedConfiguration
def inspect
  keys = self.keys.map(&:to_sym)
  "#<#{self.class}:0x#{(object_id << 1).to_s(16)} keys=#{keys.inspect}>"
end
  • object_id の表示形式は標準の inspect に合わせている
  • keys メソッド(もしくは同等のアクセサ)を使ってキーの一覧を取得
  • 値にはアクセスしないため、復号やENVアクセスによる副作用/遅延も最小限

テスト・CHANGELOG

  • combined_configuration_test.rb, encrypted_configuration_test.rb, env_configuration_test.rbinspect の期待出力に関するテストを追加
  • activesupport/CHANGELOG.md に挙動変更として記載(= パブリックな振る舞いの変更と位置づけ)

  1. 影響範囲・注意点
  • セキュリティ上は明確な改善
    ログ・コンソール・エラー画面経由でのシークレット・ENV漏洩リスクが大きく減ります。特に本番環境や共有されるログを扱う環境ではプラス。

  • inspect に値の露出を期待していたコードは壊れる
    本来そうあるべきではありませんが、もし以下のようなコードを書いていた場合は動かなくなります:

    ruby
    # NG パターン(値を取り出す目的で inspect をパースしている等)
    Rails.app.credentials.inspect.include?("secret_value")

    inspect はデバッグ用途であり、パースしてロジックに使うことは非推奨です。値が必要な場合は正規の API ([], メソッドアクセスなど) を明示的に使う必要があります。

  • デバッグ体験の変化
    これまでコンソールで

    ruby
    Rails.app.credentials

    を実行して中身の具体的な値を一覧していたワークフローは使えなくなります。今後は:

    • キー一覧: Rails.app.credentials.keys
    • 個別キーの値確認: Rails.app.credentials.some_secretRails.app.credentials[:some_secret]

    といった形で 意図的に 参照する必要があります。

  • 動作そのもの(設定の読み込み・参照など)には影響なし
    変わるのは inspect の出力だけであり、設定値の解決・利用ロジックは従来通りです。


  1. 参考情報 (あれば)
  • この PR は ActiveSupport::CombinedConfiguration, ActiveSupport::EnvConfiguration, ActiveSupport::EncryptedConfiguration の「公開インタフェースの一部」である inspect の挙動変更なので、今後の Rails バージョンアップ時には 挙動差分 として認識しておくとよいです。
  • 類似の流れとして、近年のフレームワークやライブラリでは、inspectto_s で機密情報を出さないようにするのが一般的なトレンドです(DBパスワード、APIキー、トークンなど)。今回の変更もその一環と言えます。

#53334 Deprecate built-in ActiveJob backburner adapter

マージ日: 2026/1/3 | 作成者: @dixpac

  1. 概要 (1-2文で)
    Active Job に組み込みで用意されている Backburner アダプタが「非推奨(deprecate)」としてマークされました。今後のバージョンで削除される可能性が高く、別のアダプタや実装への移行が推奨されます。

  1. 変更内容の詳細

※PR本文に説明がないため、Rails で一般的に行われる「アダプタの非推奨化」のパターンからの推測を含みますが、差分ファイル構成から見て妥当な範囲にとどめます。

2-1. CHANGELOG の更新

activejob/CHANGELOG.md に、Backburner アダプタの非推奨化が明記されました。
これにより、「このリリースから backburner アダプタは deprecated」という公式な位置付けになります。

例(イメージ):

markdown
*   Deprecate the built-in Active Job Backburner adapter.

    *dixpac*

今後のリリースノートやアップグレードガイドで、この記述が参照されることになります。

2-2. Backburner アダプタ本体への非推奨マーク

activejob/lib/active_job/queue_adapters/backburner_adapter.rb に、非推奨であることを示すコードが追加されています。Rails では典型的に以下のような形で実装されます:

  • ActiveSupport::Deprecation.warn を使った実行時警告
  • またはクラス/モジュールのコメント・doc に「Use X instead」「This adapter is deprecated」などを追記
  • 場合によっては deprecate マクロ使用

イメージコード:

ruby
module ActiveJob
  module QueueAdapters
    class BackburnerAdapter
      def initialize(*)
        ActiveSupport::Deprecation.warn(
          "Active Job's built-in Backburner adapter is deprecated " \
          "and will be removed in a future release. " \
          "Please use a custom adapter gem or another supported adapter instead."
        )
        super
      end
      # ...
    end
  end
end

※実際のコードは若干異なる可能性がありますが、行数的にこの種の deprecation 警告追加でほぼ確実です。

2-3. テストの追加

activejob/test/cases/adapter_test.rb にテストが 27 行追加されています。

想定される内容:

  • Backburner アダプタを指定したときに、deprecation warning が出ることを検証するテスト
  • assert_deprecated / assert_deprecation_warning などのヘルパを用いて、警告メッセージの存在と内容を確認
  • 既存の「各アダプタが正しく動作するか」をテストしているケースに、Backburner の deprecation を組み込んだ形

サンプルイメージ:

ruby
def test_backburner_adapter_is_deprecated
  assert_deprecated(/Backburner adapter is deprecated/) do
    ActiveJob::Base.queue_adapter = :backburner
  end
end

これにより、将来の変更で deprecation 警告が消えてしまったり、文言が意図せず変わることを防いでいます。


  1. 影響範囲・注意点

3-1. 現在 Backburner アダプタを利用しているアプリ

config/application.rb などで:

ruby
config.active_job.queue_adapter = :backburner

と設定している場合、Rails の新しいバージョンに上げると、実行時に deprecation warning が出るようになります。

対応の方向性

  • 中長期的には、以下のいずれかを検討する必要があります:
    • Backburner 用の外部 gem(コミュニティ製アダプタ)に移行
    • 別の公式サポートされているキューアダプタ(Sidekiq, Resque, Delayed Job, Que, Solid Queue など)へ移行
    • 自前で ActiveJob::QueueAdapter を実装して独自アダプタを作る

将来的に Rails 本体から backburner アダプタが削除されると、queue_adapter = :backburner は例外を投げるようになると考えられます。

3-2. テストや CI 上のノイズ

  • RSpec や Minitest で deprecation をエラー扱いにしている場合、Backburner を使ったテストが落ちる可能性があります。
  • CI のログに deprecation が大量に出るようであれば、
    • 早めのアダプタ移行
    • 一時的な deprecation フィルタリング(ActiveSupport::Deprecation.behavior 設定) などの対応が必要です。

3-3. ライブラリ/エンジン作者への影響

  • gem や Rails Engine で queue_adapter = :backburner をデフォルトにしている場合、その gem の利用者がアップデート時に deprecation を見ることになります。
  • 利用者への影響を抑えるために、README や CHANGELOG に「Backburner adapter は非推奨」「今後の対応方針」を明記しておくとよいです。

  1. 参考情報 (あれば)
  • Active Job ガイド(公式ドキュメント・英語)
    https://guides.rubyonrails.org/active_job_basics.html
    (Queue adapters セクションにサポートされているアダプタ一覧と設定方法があります)

  • 独自アダプタ実装の参考:
    ActiveJob のアダプタは一般に ActiveJob::QueueAdapter インターフェイス(enqueue, enqueue_at など)を実装したクラスとして書けます。公式ガイドや既存アダプタ(sidekiq, resque 等)の実装を参照すると、Backburner 向けの外部アダプタを作る際の参考になります。

この PR 時点では「即座に動かなくなる」変更ではなく、「公式 Backburner アダプタは今後消える前提なので、今のうちに移行を始めてください」という位置付けの変更と考えてよいです。


#56508 Remove proc support in config.revision

マージ日: 2026/1/3 | 作成者: @byroot

  1. 概要 (1-2文で)
    config.revision で Proc(ラムダ / ブロック)を指定するサポートが削除され、常に「その場で評価された値」を設定する前提の API に整理されました。これにより設定方法がシンプルになり、ガイドやテストもそれに合わせて縮小されています。

  1. 変更内容の詳細

※ PR本文は短く差分も小さいので、Rails の既存実装から推測を含めた解説になります。

2-1. config.revision の仕様整理

以前の実装では、config.revision に以下のように Proc を渡すことが可能だったと考えられます。

ruby
# 旧: Proc を渡すケース (今回削除された使い方)
config.revision = -> { `git rev-parse HEAD`.chomp }

アプリケーション内部ではこの Proc が「後から呼び出される」か、「即時に呼び出した結果を使う」かの分岐が存在していました。

今回の PR では、「どうせすぐ呼び出して値にしてしまう」ように振る舞いが変わったため、わざわざ Proc を受け付ける意味がなくなり、Proc サポート自体が削除されています。

結果として、推奨される書き方は次のようになります。

ruby
# 新: 値をその場で評価して代入する
config.revision = `git rev-parse HEAD`.chomp

あるいは、環境変数などの静的な値を使う場合:

ruby
config.revision = ENV["APP_REVISION"] # 文字列などの即値のみ

Rails コア側の実装 (Rails::Application 付近) からは:

  • config.revision が Proc かどうかを判定するコード
  • Proc なら call して結果を使うロジック

といった分岐が削除され、常に「単なる値(String など)」として扱うようになっています。

2-2. ガイドとテストの変更

  • guides/source/configuring.md
    • config.revision の説明から Proc を使う例や記述が削除され、「値を直接設定する」前提の説明に整理されています。
  • railties/test/application/app_revision_test.rb
    • Proc を設定したときの挙動を確認していたテストケースが削除され、もはや Proc をサポートしていない仕様が明確になりました。

行数の統計からも、機能削除に伴うテストとドキュメントの簡素化が中心で、追加はほぼ「仕様を明示するための最小限の変更」のみです。


  1. 影響範囲・注意点

3-1. 影響を受けるコード

次のようなコードを書いている場合は壊れます:

ruby
# NG となるコード (この PR 後はサポートされない)
config.revision = -> { ENV.fetch("APP_REVISION") }
config.revision = proc { `git rev-parse HEAD`.chomp }

この PR により config.revision に Proc を渡すこと自体が非対応になったため、
Rails をこのバージョン以降に上げると、起動時にエラー or 期待しない値になる可能性があります。

3-2. 移行方法

以下のように「その場で評価した結果を代入」する形に書き換えてください。

ruby
# よくある置き換えパターン

# Before
config.revision = -> { `git rev-parse HEAD`.chomp }

# After
config.revision = `git rev-parse HEAD`.chomp
ruby
# Before
config.revision = -> { ENV["APP_REVISION"] || "unknown" }

# After
config.revision = ENV["APP_REVISION"] || "unknown"

Proc にしていた理由が「遅延評価したい」ことであれば、今回の仕様では
config.revision はあくまで「起動時に一度決める固定値」として扱う設計に寄せられたと理解するのが安全です。
リクエストごとに変わる値や重い計算をしたい場合は、別のレイヤ(ミドルウェアやサービスクラス)で扱う必要があります。

3-3. ランタイムでの変更について

config.revision は Rails の設定オブジェクトなので、「起動後に差し替える」ことを前提にはしていません。
この PR により、設定値は純粋なオブジェクト(多くは String)であることが暗黙的に強くなったため、
「Proc を使ってランタイムで変わる値にしたい」といった用途には向かなくなっています。


  1. 参考情報 (あれば)
  • PR: https://github.com/rails/rails/pull/56508
  • 近いコンテキストとして、config.revision は Heroku 等のデプロイ環境で「アプリのリビジョン(Git SHA など)」を格納し、
    エラーレポートやメトリクス、ヘルスチェックページ等から参照する用途を想定した設定項目です。
  • 将来の Rails リリースノートやアップグレードガイドで「config.revision から Proc サポートが削除された」旨が記載される可能性が高いので、
    バージョンアップ時はその記述も併せて確認すると安全です。

#56507 Remove non existing autoload for sucker punch

マージ日: 2026/1/2 | 作成者: @morgoth

  1. 概要 (1-2文で)
    Active Job のキューアダプタ定義から、存在しない「sucker_punch」関連の autoload 設定が1行削除されました。
    古いコミットの「消し残し」を整理する、挙動にはほぼ影響しないリファクタリングです。

  1. 変更内容の詳細(あればサンプルコードも含めて)

対象ファイル:

  • activejob/lib/active_job/queue_adapters.rb

削除されたのは、ActiveJob::QueueAdapters モジュール内の autoload 設定の1行です。イメージとしては次のようなコードが削除されています:

ruby
module ActiveJob
  module QueueAdapters
    # こういった autoload 群の中に
    # autoload :SuckerPunch, "active_job/queue_adapters/sucker_punch_adapter"
    # のような1行が削除された
  end
end

説明文にある通り、この autoload は以下のコミット後の「残骸」とみなされています:

そのコミット側で Sucker Punch 関連のサポートやクラス定義が削除・変更されたにもかかわらず、autload 行だけが残っていたため、今回の PR で整理された形です。


  1. 影響範囲・注意点
  • Rails/Active Job から公式に提供される sucker_punch キューアダプタに依存しているコードは、既に前のコミット時点で実質的に壊れているか、非サポート状態になっています。この PR はそれを明示的にクリアにする小さな整理です。
  • 現時点で ActiveJob::QueueAdapters::SuckerPunch を直接参照していた場合:
    • そのクラス/モジュール自体が以前のコミットで無くなっているか、ロードされない状態になっている可能性が高く、今回の PR だけが原因で壊れるケースはほとんどありません。
  • Sucker Punch を使いたい場合:
    • 独自の queue adapter を定義して利用するか、
    • すでにメンテされている外部 gem(あれば)を利用する必要があります。
  • アプリ側で autoload ではなく、require "active_job/queue_adapters/sucker_punch_adapter" のような直接ロードをしている場合:
    • ファイル自体が存在しない/削除済みであれば、LoadError が発生します。
    • これはこの PR ではなく、すでに行われた Sucker Punch サポート削除側の変更の影響です。

  1. 参考情報 (あれば)

#56490 Add Rails.app.revision

マージ日: 2025/12/31 | 作成者: @byroot

  1. 概要 (1–2文で)
    Rails.app.revision という新しいAPIが追加され、アプリケーションの「リビジョン(デプロイごとの識別子)」をRails側からシンプルに参照できるようになりました。デプロイトラッキング、エラーレポート、監視、キャッシュキーなどで、統一的にアプリのバージョン/リビジョンを扱うための仕組みです。

  1. 変更内容の詳細

※PR本文から読み取れる範囲での要約になります。実際のコードは概ね以下のような形の機能を提供していると考えられます。

2-1. Rails.app.revision の追加

Rails.application に対応する形で、グローバルにアプリケーションのリビジョンを取得できるAPIが追加されています:

ruby
Rails.app.revision
# => "20250101-abcdef" など(環境に応じた値)

想定される用途:

  • デプロイごとのリビジョンIDをログやメトリクスに載せる
  • エラーレポーティングサービス(Sentry など)への release/version として渡す
  • ヘルスチェック / info エンドポイントでアプリのバージョン情報を返す
  • キャッシュキーにリビジョンを混ぜて、リリース単位でキャッシュ無効化を行う など

2-2. アプリケーション設定 (Rails::Application::Configuration) の拡張

config/application.rb 経由で設定できるように、configurationrevision が追加されています。たとえば:

ruby
# config/application.rb
module MyApp
  class Application < Rails::Application
    config.revision = ENV["APP_REVISION"] || `git rev-parse HEAD`.chomp
  end
end

これにより、アプリ起動時に任意の値をリビジョンとして設定でき、以後 Rails.app.revision から参照できるようになります。

2-3. ブートストラップ処理での初期化

rails/application/bootstrap.rb にも変更があり、ブートシーケンスのどこかで revision を初期化/確定する処理が追加されています。

可能性としては:

  • 設定されていれば config.revision を使用
  • なければ環境変数 (例: ENV["RAILS_APP_REVISION"] など) を見る
  • それもなければ Git 情報や、REVISION ファイルなど、一般的なデプロイの慣習を利用

といったフォールバックを行う実装が考えられます(PR #56080 の修正とあるので、前回の実装のバグや不整合を解消した整理版の実装とも言えます)。

2-4. Rails::Info への統合

railties/lib/rails/info.rb にも追記されているため、rails info やアプリから提供される「Rails info」ページに、アプリケーションのリビジョンが表示されるようになっています。

例:

bash
$ bin/rails info
# 中略
Application revision: 20250101-abcdef

2-5. ガイド・CHANGELOG・テストの追加

  • guides/source/configuring.md
    アプリケーション設定のガイドに、config.revision / Rails.app.revision の設定・利用方法が記載されています。
  • railties/CHANGELOG.md
    Rails本体の変更履歴に、この新APIが追加されたことが明記されています。
  • railties/test/application/app_revision_test.rb
    revision の決定ロジックや公開APIの挙動を確認するテストが追加され、仕様が固定化されています。

  1. 影響範囲・注意点
  • 新機能であり、既存コードを壊さない
    既存アプリで特に設定しなければ、Rails.app.revisionnil もしくはデフォルトの値になるだけで、既存挙動を壊す変更ではありません。

  • デプロイフローとの統合がポイント
    実用的に使うには、CI/CDなどデプロイプロセスのどこかで一貫したリビジョン値をセットする必要があります。

    • 例: ENV["APP_REVISION"] をCIでGit SHAに設定 → config.revision = ENV["APP_REVISION"]
    • 例: Capistrano系のデプロイなら REVISION ファイルを生成し、それを読むロジックを config.revision に書く など
  • キャッシュキーに組み込む場合の注意
    リビジョンをキャッシュキーに混ぜると、「デプロイのたびにキャッシュがリセットされる」挙動になります。キャッシュミス増加とトラフィックに注意しつつ、意図した箇所だけに適用するのが安全です。

  • エラーレポート・監視との連携
    監視/エラートラッキングの初期化処理で Rails.app.revision を見に行くようにしておくと、コードベースに依存せずリビジョン取得方法を差し替えられます。

    ruby
    Sentry.init do |config|
      config.release = Rails.app.revision
    end

  1. 参考情報 (あれば)
  • 修正対象となったPR: https://github.com/rails/rails/pull/56080
    (本PRは、その修正・改良版として Rails.app.revision を整備している)
  • 設定ガイド (guides/source/configuring.md) に、実際の設定例や推奨の使い方が追記されているため、詳細な利用方法はそちらを参照するとよいです。