Array#to_query が空要素を除外するよう修正

rails/rails

Array#to_query が空の配列要素をクエリ文字列に残す問題を修正し、空ハッシュ要素と同様にスキップするようになりました。これにより、ネストしたパラメータ生成時の不整合が解消されます。

背景

Array#to_query が空配列要素を除外しないという不整合がありました。[].to_query(prefix)nil.to_query(prefix) に委譲し空文字列になるのに対し、空配列要素は nil にならず、キーだけがエスケープされた a%5B%5D%5B%5D が残ります。その結果、{ a: [1, [], 2] }.to_query が期待される "a%5B%5D=1&a%5B%5D=2" ではなく、余分なセグメントを含む文字列を生成していました。

技術的な変更

Array#to_query の実装に空コレクションのガードを追加しました。変更前は各要素を value.to_query(prefix) に変換し、空文字列でなければ結合していましたが、以下のように空ハッシュまたは空配列を事前にスキップするロジックを挿入しました。

@@ -60,8 +60,8 @@ def to_query(key)
       nil.to_query(prefix)
     else
-        q = value.to_query(prefix)
-        q unless q.empty?
+        next if (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
+        value.to_query(prefix)
       }.join "&"
     end
   end

この変更により、空のハッシュ要素と同様に空配列要素もクエリ文字列に含まれなくなります。トップレベルで [].to_query("a") が "a%5B%5D" を返す既存の振る舞いは、別の if empty? ブランチで処理されるため影響を受けません。

テストケースを追加して回帰防止を確実にしました。新たに test_array_with_empty_arrayactivesupport/test/core_ext/object/to_query_test.rb に追加され、空配列要素を含む配列が正しく "a%5B%5D=1&a%5B%5D=2" にシリアライズされることを検証します。

@@
   def test_array_with_empty_hash
     assert_query_equal "a%5B%5D=1&a%5B%5D=2", a: [1, {}, 2]
   end
+
+  def test_array_with_empty_array
+    assert_query_equal "a%5B%5D=1&a%5B%5D=2", a: [1, [], 2]
+  end

テストは修正前に失敗し、修正後に通過することが CI で確認されています。

設計判断

既存の空コレクション判定ロジックを再利用する形で最小限の変更に留めました。Hash#to_query ですでに採用されている next if (value.is_a?(Hash) || value.is_a?(Array)) && value.empty? をそのまま Array#to_query に持ち込み、コード重複を避けつつ挙動の一貫性を確保しています。加えて、トップレベルの空配列は別ブランチで処理されるため互換性が保持され、既存アプリケーションへの影響はありません。

まとめ

この PR は、Array#to_query が空配列要素をクエリ文字列に残す不具合を修正し、Hash#to_query と同様のスキップロジックを導入しました。3 行程度のシンプルな差分で挙動の一貫性を実現し、追加テストにより将来的なリグレッションを防止します。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
124df15a

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文、背景、技術的な変更、設計判断、まとめがすべて揃っており、総論→各論→結論の構成が明確です。

カスタムMarkdown構文 ⚠ WARNING

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

コードブロックのファイル名付きシンタックスハイライトは正しい形式です。GitHubリンクは PR 番号をリンク化していますが、形式が "[PR #57677](URL)" となっており、要件の "[#123](URL)" とは完全に一致していません。

対象読者への適合性 ✓ PASS

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

Rails の内部実装に関する説明で、エンジニア向けの適切な技術レベルです。過度な初心者向け解説はありません。

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

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

各セクションは総論・各論・結論のパラグラフ構成が整っており、トピックセンテンスで始まり、1段落1トピック、6文以内で記述されています。段落間は空行で区切られています。

Diff内容との照合 ✓ PASS

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

記事中のコードブロックは提供された Diff と完全に一致し、ファイル名・変更箇所も正しく示されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている技術用語(to_query、空コレクション、ガード、回帰防止 etc.)は PR と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

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

技術的な主張は Diff および PR 説明と合致しており、因果関係も正しく述べられています。

事実の突合 ✓ PASS

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

記事のすべての事実は PR のタイトル・説明・Diff に裏付けられており、推測や外部知識の付加はありません。

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

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

PR 番号 #57677 などの固有名詞は正確です。数値的な記述はありません。

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

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

記事タイトルは PR の内容を正確に要約しており、一致しています。

外部知識の正確性 ✓ PASS

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

バージョンサポートやリリース日程といった外部情報は含まれていません。

時間表現の正確性 ✓ PASS

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

時間表現は使用されておらず、PR の記述と矛盾はありません。