`render_in` シグネチャを Rails の `**options` 対応に更新
Rails が render_in のシグネチャに **options を追加した変更に対し、ViewComponent 側でも **_ を受け取れるよう対応しました。後方互換性を維持しながら、Rails の新しいレンダリングインターフェースとの整合性を確保する最小限の変更です。
背景
Rails の #50623 により、render_in のシグネチャが render_in(view_context, &block) から render_in(view_context, **options, &block) へと変更されました。この変更は、locals: { ... } のような呼び出し側の引数やブロックを render_in に渡せるようにするためのものです。
これまでの #render_in サポートは、インスタンスが描画に必要なコンテキストをすべて自前で持つことを前提としており、呼び出し側から locals やブロックを渡す手段がありませんでした。Rails 本体はこの制約を解消する方向に進んでおり、ViewComponent 側も新しいシグネチャに追従する必要が生じました。
技術的な変更
render_in を定義している 3 つのクラスすべてで、引数リストに **_ を追加することで新しいシグネチャに対応しました。変更対象は ViewComponent::Base、ViewComponent::Collection、ViewComponent::Instrumentation の 3 ファイルです。
変更の内容はいずれも同一パターンです:
変更前:
def render_in(view_context, &block)
変更後:
def render_in(view_context, **_, &block)
**_ はキーワード引数を受け取って破棄する慣用句で、渡されたオプションを現時点では利用しないが、メソッドシグネチャとして受け付けることを明示しています。ViewComponent::Collection と ViewComponent::Instrumentation でも同様の変更が適用されています。
テストファイル test/sandbox/test/rendering_test.rb では、test_collection_component_missing_custom_parameter_name_with_activemodel の挙動が変更されています。Rails main では ViewComponent::MissingCollectionArgumentError より先に ActiveModel::UnknownAttributeError が発生するケースがあるため、どちらの例外クラスも許容するよう修正されています。またアロケーション数の期待値も調整されています。
設計判断
**_ による「受け取って捨てる」パターンを採用することで、既存の render_in(view_context, &block) 形式の呼び出しへの後方互換性を維持しています。PR の説明にも「**options はオプショナルなパラメータのため後方互換性は保たれる」と明示されています。
ViewComponent は現時点では受け取った options を実際のレンダリングに利用しておらず、Rails 側の新シグネチャとの互換性を確保することが今回の目的です。渡されたオプションを活用する実装は将来の課題として残されています。
まとめ
Rails の render_in シグネチャ変更に対して、**_ を 3 か所に追加するだけで対応を完結させた、最小コストの互換性維持パッチです。破棄パターンの採用により既存コードへの影響をゼロに抑えつつ、Rails 本体の進化に追従する設計判断が読み取れます。