LoginSignup
8
2

More than 1 year has passed since last update.

ActionView を単体で使用する(6.0以降対応)

Last updated at Posted at 2021-01-11

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に保存しています。

参考

追記(2022/6/21)

Rails 7 でも動作確認しました。

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2