'Render js.erb view on Rails 6

I have a view in the file APP/views/js/library.js.erb file, it contains:

bar: <%= raw @foo %>   

On Rails 4 I got the content of that view using:

av = ActionView::Base.new(Rails.root.join('app', 'views'))
av.assign({ foo: my_dynamic_variable })
av.render(template: 'js/library')

but on Rails 6 I'm getting:

NoMethodError: undefined method `html_fallback_for_js' for 
"app/views/js/library":String
from /home/manuel/.rvm/gems/ruby-3.0.2/gems/actionview- 
6.1.4.1/lib/action_view/base.rb:264:in `in_rendering_context'


Solution 1:[1]

In Rails 6.1:

lookup_context = ActionView::LookupContext.new(ActionController::Base.view_paths)

context = ActionView::Base.with_empty_template_cache.new(lookup_context, {}, nil)

renderer = ActionView::Renderer.new(lookup_context)

renderer.render(context, { file: 'app/views/template.html.erb' })
  • ActionView::Renderer.new() takes a lookup_context arg, and render() method takes a context, so we set those up first
  • ActionView::Base is the default ActiveView context, and must be initialized with with_empty_template_cache method, else render() will error
  • The {}, nil are required assigns and controller args, which used to default to {}, nil in Rails 5
  • Rails 6.1 requires a full filepath file: 'app/views/template.html', whereas Rails 5 only required the filename

Solution 2:[2]

This is the new way:

 ApplicationController.render(template: '/js/library.js.erb',
 locals: { categories: 'categories', periods: 'periods' },
 assigns: assigns,  handlers: [:js],  formats: [:js] )

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Csala
Solution 2