ActionView を単体で利用する場合は、ActionView 5.2 までは次のようなコードを書いていました。
def html
view_context.assign(staffs: [{ name: 'Alice', position: 'supervisor' }])
view_context.render(template: 'index',
prefixes: 'staffs')
end
def lookup_context
return @lookup_context if @lookup_context
@lookup_context = ActionView::LookupContext.new('./views')
@lookup_context.cache = false
@lookup_context
end
def view_context
@view_context ||= ActionView::Base.new(lookup_context)
end
p html
ActionView 6.0 からは同じコードを利用していると、次のような WARNING が発生していました。
DEPRECATION WARNING: ActionView::Base instances must implement `compiled_method_container` or use the class method `with_empty_template_cache` for constructing an ActionView::Base instance that has an empty cache. (called from html at app.rb:13)
また、2020/12にリリースされた ActionView 6.1 からは ActionView::Base.new
でシンタックスエラーが発生するようになりました。
Traceback (most recent call last):
7: from app.rb:41:in `<main>'
6: from app.rb:6:in `execute'
5: from app.rb:6:in `open'
4: from app.rb:7:in `block in execute'
3: from app.rb:12:in `html'
2: from app.rb:27:in `view_context'
1: from app.rb:27:in `new'
/Users/soruma/program/only_action_view_6_1_example/vendor/bundle/ruby/2.7.0/gems/actionview-6.1.1/lib/action_view/base.rb:230:in `initialize': wrong number of arguments (given 1, expected 3) (ArgumentError)
WARNING に書かれている通り、
ActionView :: Baseインスタンスは、
compiled_method_container
を実装するか、空のキャッシュを持つActionView::Baseインスタンスを構築するためにクラスメソッドwith_empty_template_cache
を使用する必要があります。
に変更しなければなりません。
Google先生に聞いても答えが出てきませんでいたが、 ActionView のテストにヒントが書かれていました。
@view = Class.new(ActionView::Base.with_empty_template_cache) do
def view_cache_dependencies; []; end
def combined_fragment_cache_key(key)
[ :views, key ]
end
end.with_view_paths(paths, @assigns)
今回、私はRails 6.1対応するにあたって次のように実装しました。
def html
view(staffs: Staff.new.execute).render(template: 'index',
prefixes: 'staffs')
end
def view(assigns)
Class.new(
ActionView::Base.with_empty_template_cache
).with_view_paths('./views', assigns)
end
今回のソースはGithubに保存しています。
参考
- ActionView を単体で使ってみる | そんなこと覚えてない
- rails/actionview/test/template/render_test.rb | Github rails/rails
- Move compiled ERB to an AV::Base subclass | Github
追記(2022/6/21)
Rails 7 でも動作確認しました。