`ActionText::Editor::Tag#render_in` のシグネチャ不整合を修正

rails/rails

#50623 で導入された render_in の新しい呼び出し規約に対し、ActionText::Editor::Tag が追従できていなかったバグを修正しました。シグネチャを (view_context, ...) に拡張することで、サブクラスが super を安全に呼び出せるようになります。

背景

render_in の呼び出し規約は #50623 で変更されておりActionText::Editor::Tag はその変更に追従できていませんでした。#50623 以降、ActionView::Template::Renderable#renderrender_in のアリティが1でない場合に renderable.render_in(context, locals: locals, &@block) を呼び出します。つまり、第2引数以降を受け取れないシグネチャでは ArgumentError: wrong number of arguments (given 2, expected 1) が発生します。

組み込みの TrixEditor::Tag はこの問題を踏んでいませんでした。render_in を独自に実装しており、super を呼び出さないためです。しかし、ドキュメントに示されているアダプターパターン render_in(view_context, ...) に従って super を呼び出すサードパーティのサブクラスは、この問題に直撃します。実際にBasecamp の Lexxy が Rails main ブランチの CI で本件を踏んでいます。

この非互換は、既存の #render_in(view_context) シグネチャを deprecated としつつ新しい規約への移行を促した #50623 の変更が、Action Text 側に反映されないまま残っていたことに起因します。

技術的な変更

actiontext/lib/action_text/editor.rbActionText::Editor::Tag#render_in のシグネチャを1行変更するだけで修正されています。

変更前:

def render_in(view_context)
  options[:class] ||= "#{editor_name}-content"

  view_context.content_tag(element_name, nil, options, &@block)
end

変更後:

def render_in(view_context, ...)
  options[:class] ||= "#{editor_name}-content"

  view_context.content_tag(element_name, nil, options, &@block)
end

Ruby の ...(forwarding argument) を使うことで、Action View が渡す locals: キーワード引数やブロックをそのまま受け取れるようになります。メソッド本体は view_context しか使わないため、追加の引数は転送も処理もされません。

あわせて actiontext/test/unit/editor/tag_test.rb が新規追加され、super を呼び出すサブクラスが例外なく動作することを確認するリグレッションテストが追加されています。

class TagSubclassCallingSuper < Editor::Tag
  def render_in(view_context, ...)
    super
  end
end

test "subclasses can call super from #render_in" do
  assert_nothing_raised do
    render(TagSubclassCallingSuper.new("trix"))
  end
end

設計判断

... による引数フォワーディング を採用したことが、この修正の核心です。追加引数を個別に名前付きで受け取るのではなく、... で一括して受け流すことで、メソッド本体を一切変えずに呼び出し規約の変化に対応しています。

この設計は、render_in の本体が locals: などの追加引数を実際には使わないという事実と整合しています。不要な引数を明示的に受け取って無視するよりも、... で「関知しない」と表明する方が意図を明確に伝えます。また、将来 Action View 側の呼び出し規約がさらに変化しても、このメソッドシグネチャを再修正する必要がなくなります。

まとめ

1行のシグネチャ変更でありながら、render_in の呼び出し規約の進化に対する Action Text の追従漏れという根本原因を正確に修正しています。... の活用により、呼び出し側の変化をサブクラスに透過的に転送する設計が実現されており、アダプターパターンを実装するサードパーティ製エディターの互換性が回復します。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
9b0264a2

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文(総論)→背景・技術的変更・設計判断(各論)→まとめ(結論)という構成が明確であり、ガイドラインに完全に準拠しています。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きシンタックスハイライト、PR番号のリンク記法ともに正しく使用されています。

対象読者への適合性 ✓ PASS

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

専門用語が適切に使用され、過度な説明がなく、専門知識を持つエンジニアという対象読者に適合した内容です。

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

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

各セクションが総論→各論の構成になっており、各パラグラフはトピックセンテンスで始まり、1段落1トピックの原則が守られています。非常に読みやすい構成です。

Diff内容との照合 ✓ PASS

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

記事内のコードブロックは、提供されたDiffの内容を正確に反映しています。ファイル名も一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「シグネチャ」「アリティ」「forwarding argument」などの技術用語が文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

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

ArgumentErrorが発生する原因や、`...` を用いた解決策の説明は、PR情報と照らして技術的に正確かつ論理的です。

事実の突合 ✓ PASS

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

記事内のすべての主張(#50623での変更、Lexxyでの問題発覚など)は、提供されたPR情報によって裏付けられています。ハルシネーションは見受けられません。

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

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

PR番号(#50623, #57356)やクラス名、ファイルパスなどの固有名詞はすべて正確です。

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

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

記事のタイトルはPRの主題「`ActionText::Editor::Tag#render_in`がキーワード引数を受け入れるように修正」を「シグネチャ不整合を修正」と的確に要約しており、内容と一致しています。

外部知識の正確性 ✓ PASS

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

記事内容はPR情報およびPR内で参照されている情報(#50623)に基づいており、根拠のない外部知識の追加はありません。

時間表現の正確性 ✓ PASS

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

「〜で導入された」「追従できていなかった」など、過去と現在の事象を区別する時間表現はPRの内容と一致しており、正確です。