Proc と Regexp の filter_attributes を filter_parameters への同期から除外

rails/rails

Rails 8.1 で ActiveRecord::FilterAttributeHandler がモデルの filter_attributesRails.application.config.filter_parameters に同期する際、ProcRegexp が文字列化されて不要なエントリが生成されていました。この PR はそれらを除外し、設定配列の安定性と可読性を向上させます。

背景

filter_attributes はシンボル・文字列に加えて ProcRegexp も受け取りますが、同期処理が全要素を to_s で文字列化していたため、"user.#<Proc:0x...>""user.(?i-mx:secret)" といった実行不可能なフィルタが filter_parameters に蓄積されました。これらはログフォーマッタや診断ツールに露出し、ブートごとにオブジェクト ID が変わるため配列が不安定になるという実務上の問題がありました。

その結果、パラメータロギングで本来のフィルタ以外のゴミが増えるだけでなく、 Proc の文字列表現が含まれることで設定が読みにくくなっていました。

技術的な変更

apply_filter メソッドに型チェックを導入し、SymbolString のみfilter_parameters へ同期するよう変更しました。具体的には case 文で属性の型を判定し、対象外の型はスキップします。

変更前:

klass_name = klass.name ? klass.model_name.element : nil
filter = [klass_name, attribute.to_s].compact.join(".")
app.config.filter_parameters << filter unless app.config.filter_parameters.include?(filter)

変更後:

case attribute
when Symbol, String
  klass_name = klass.name ? klass.model_name.element : nil
  filter = [klass_name, attribute.to_s].compact.join(".")
  app.config.filter_parameters << filter unless app.config.filter_parameters.include?(filter)
end

この変更に伴い、railties/test/application/active_record_railtie_test.rb にテストが追加され、ProcRegexpfilter_parameters に混入しないことを自動的に検証しています。

テスト例:

class Post < ActiveRecord::Base
  self.table_name = "posts"
  self.filter_attributes += [:special_attr, /secret/i, ->(key, value) { value.reverse! }]
end

assert_includes Rails.application.config.filter_parameters, "post.special_attr"

garbage = Rails.application.config.filter_parameters.grep(String).select do |filter|
  filter.include?("#<Proc") || filter.include?("(?i-mx:")
end
assert_empty garbage

設計判断

apply_filter型限定 を行う実装は、既存の filter_attributes API を変更せずに問題を解決する保守的な選択です。ProcRegexp は依然として ActiveSupport::ParameterFilter によってグローバルに機能しますが、文字列化して filter_parameters に流す必要がなくなったため、設定配列の 安定性可読性 が向上しました。

このアプローチは、追加の設定キーやオプションフラグを導入する代わりに、既存コードパスに最小限の分岐を加えることで後方互換性を保ちつつ、実装上のゴミデータ生成を防いでいます。

まとめ

apply_filter がシンボルと文字列のみを filter_parameters に同期するよう変更されたことで、ProcRegexp に起因する不要な文字列エントリが除去され、設定配列の安定性と可読性が向上しました。既存のフィルタ機構はそのまま維持され、Rails アプリ全体のロギング設定がクリーンになる効果があります。

記事メタデータ

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

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文、背景、技術的変更、設計判断、まとめの5セクションが揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ✓ PASS

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

コードブロックは ````ruby:ファイルパス```` 形式で正しく記述され、PRリンクは [PR #57580](URL) 形式で#付きリンクになっています。

対象読者への適合性 ✓ PASS

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

Rails エンジニア向けの専門的な内容で、初心者向けの余計な解説はありません。

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

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

各セクションは総論・各論・結論のパラグラフ構成になり、トピックセンテンスが先頭に配置され、1段落は1トピック、長さも適切です。空行で区切られています。

Diff内容との照合 ⚠ WARNING

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

`filter_attribute_handler.rb` の変更はDiffと完全に一致していますが、テストコードはメソッド名・`app "development"` 呼び出しなどのラッパーが省略されています。重要なロジックは示されているため理解には支障なしと判断しWARNINGとしました。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

filter_attributes、filter_parameters、Proc、Regexp などの用語が正確に使用されています。

説明の技術的正確性 ✓ PASS

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

変更理由・実装内容・影響がPRの記述と一致しており、技術的に誤りはありません。

事実の突合 ✓ PASS

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

すべての主張がPRのタイトル・説明・Diffで裏付けられており、捏造や推測はありません。

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

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

PR番号 #57580 が正しく記載されており、他の数値や固有名詞の誤りはありません。

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

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

記事タイトルはPRタイトル「Skip Proc and Regexp filter_attributes when syncing to filter_parameters」の意味を正確に日本語化しています。

外部知識の正確性 ✓ PASS

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

Rails のバージョンサポートやリリーススケジュール等、PRに記載されていない外部情報は含まれていません。

時間表現の正確性 ✓ PASS

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

時間表現は使用されておらず、PR内容と食い違いもありません。