`ActionText::Editor::Tag#render_in` のシグネチャ不整合を修正
#50623 で導入された render_in の新しい呼び出し規約に対し、ActionText::Editor::Tag が追従できていなかったバグを修正しました。シグネチャを (view_context, ...) に拡張することで、サブクラスが super を安全に呼び出せるようになります。
背景
render_in の呼び出し規約は #50623 で変更されており、ActionText::Editor::Tag はその変更に追従できていませんでした。#50623 以降、ActionView::Template::Renderable#render は render_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.rb の ActionText::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 の追従漏れという根本原因を正確に修正しています。... の活用により、呼び出し側の変化をサブクラスに透過的に転送する設計が実現されており、アダプターパターンを実装するサードパーティ製エディターの互換性が回復します。