`ActionController::Parameters#merge` が複数引数に対応し `Hash#merge` と完全に一致

rails/rails

ActionController::Parameters#merge および #merge! が複数のハッシュを同時に受け取れるようになりました。これにより、Ruby の Hash#merge との挙動の一貫性が完全に整います。

背景

ActionController::Parameters#merge / #merge! は、Ruby の Hash#merge と一貫したAPIを提供することを目指してきましたが、段階的な改善の途上にありました。#56410 では #merge へのブロックサポートが追加され、#merge! との非対称性が解消されました。しかし、Ruby 3.2 以降の Hash#merge が複数引数を受け付けるのに対し、Parameters#merge / #merge! はいずれも引数を1つしか受け取れないという制約が残っていました。

本 PR #56575 はその最後のギャップを埋め、Parametersmerge 系メソッドを Hash#merge と完全に揃えます。

技術的な変更

actionpack/lib/action_controller/metal/strong_parameters.rb#merge#merge! の引数シグネチャが other_hash から *other_hashes に変更され、可変長引数を受け付けるようになりました。

変更前:

def merge(other_hash, &block)
  new_instance_with_inherited_permitted_status(
    @parameters.merge(other_hash.to_h, &block)
  )
end

def merge!(other_hash, &block)
  @parameters.merge!(other_hash.to_h, &block)
  self
end

変更後:

def merge(*other_hashes, &block)
  new_instance_with_inherited_permitted_status(
    @parameters.merge(*other_hashes.map!(&:to_h), &block)
  )
end

def merge!(*other_hashes, &block)
  @parameters.merge!(*other_hashes.map!(&:to_h), &block)
  self
end

変更の核心は other_hashes.map!(&:to_h) です。可変長引数で受け取った各ハッシュに対して to_h を呼び出すことで、ActionController::Parameters インスタンスも通常の Hash も一様に内部表現へ変換し、そのままスプラット展開して @parameters.merge! / @parameters.merge に委譲しています。

以下のように複数のパラメータや通常のHashを一度にマージできます:

params1 = ActionController::Parameters.new(a: 1)
params2 = ActionController::Parameters.new(b: 2)
params1.merge(params2, { c: 3 })
# => #<ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>

引数を1つだけ渡す従来の使い方はそのまま動作するため、既存のコードへの影響はありません。

設計判断

map!(&:to_h) を使った最小限の実装 が選ばれました。

各引数に対して個別に to_h を呼び出す処理を map! で一括化し、スプラット展開で内部の Hash#merge / Hash#merge! へそのまま渡す構造は、追加のループやデータ構造を必要とせず簡潔です。ブロック引数の扱いも含め、変更箇所は引数の受け取り方と to_h の適用方法のみであり、既存の new_instance_with_inherited_permitted_status による許可状態の継承ロジックには一切手を加えていません。

この設計は、ParametersHash のラッパーとして振る舞うという既存のアーキテクチャを踏襲しており、複数引数への対応を Hash 側に委譲することで実装の複雑さを最小化しています。

まとめ

本 PR (#56575) により、ActionController::Parameters#merge / #merge! は Ruby の Hash#merge と引数の互換性が完全に一致しました。#56410 から続く段階的な整合化の取り組みが完結し、ParametersHash と同様に扱うコードがより自然に書けるようになります。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
3cf24566

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「リード文(総論)→背景・技術詳細(各論)→まとめ(結論)」の3部構成が明確です。各セクションが適切な役割を果たしており、非常に理解しやすい構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```ruby:path/to/file.rb)やPR番号のリンク記法([#123](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門用語やコードの文脈がRails開発者を対象としており、冗長な説明がなく適切です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが「総論→各論→結論」で構成され、各段落はトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られており、可読性が非常に高いです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロック(変更前・変更後、および使用例)は、提供されたDiff情報と完全に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「可変長引数」「スプラット展開」「ActionController::Parameters」など、使用されている技術用語はすべて正確かつ文脈に適しています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「*other_hashes」や「map!(&:to_h)」の役割に関する説明は、コードの動作を技術的に正しく解説しています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内の主張はすべてPRのDescription、Diff、参照されている過去のPRで裏付けられています。「設計判断」セクションはコードから読み取れる妥当な解説であり、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#56575, #56410)やバージョン番号(Ruby 3.2)など、すべての数値・固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRの主題「`Parameters#merge`の複数引数対応」を正確かつ簡潔に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

「Ruby 3.2」に関する言及は、PR Descriptionで参照されている公式ドキュメントに依拠しており、外部知識の捏造はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「段階的な改善」「最後のギャップを埋める」といった時間表現は、PRの文脈(過去のPRからの改善)と一致しており正確です。