23

I've created a json view with JBuilder. But I want to preload this into a data object, so Backbone has access to the data early on without fetching for it.

How can I render the list.json.jbuilder view into my list.html.erb view?

Normally without jbuilder, I'd do something like this:

<div data-list="<%= @contents.to_json %>"></div>
Jareish
  • 772
  • 2
  • 9
  • 24

1 Answers1

23

render, when called from within a view, returns a string rendering of the passed template or partial; you can embed that string into your view as you like. Note though that:

  • You have to append your template name with the type suffix/extension. If you don't, Rails may get confused about which template file you're calling; ie: it might choose list.html.erb instead of list.json.jbuilder. If you're making this call from list.html.erb, trying to render list.html.erb results in infinite recursion and a SystemStackError. Using the :format option for render doesn't appear to work.
  • You have to specify the qualified path to the template; it won't find the right template for "list.json" just because list.json.jbuilder resides in the same directory as list.html.erb.
  • You need to pass the output of the render call through raw; otherwise, it will get escaped when it gets embedded into the view.

So, for your example, you might write this, assuming your templates were in /app/views/foo:

<div data-list="<%= raw render(:template => "foo/list.json", :locals => { :contents => @contents }) %>"></div>
Craig Walker
  • 49,871
  • 54
  • 152
  • 212
  • 4
    This is such a protip! Thanks. You can also use `<%== %>` instead of `raw` – Mark G. Jan 08 '15 at 20:53
  • I was challenged to render a html partial as json propery with jbuilder. render does the job here as well json.prop render(:template => 'partials/_resort_summary', :locals => {resort: @resort}) – dc10 Apr 08 '15 at 20:02
  • Thank you very much. I have spent quite some time figuring out how I'd do this. – Ifelere Bolaji Nov 24 '16 at 22:35
  • Great answer @Craig Walker. I'd like to add that you need to include the word `template` if you want to use a jBuilder file that doesn't start with an underscore. Reading the official Rails Guides one gets the impression that this is optional, but it makes a difference in this situation: https://guides.rubyonrails.org/layouts_and_rendering.html#using-render (section 2.2.2). So `<%= raw render template: "foo/list.json.jbuilder" %>` works in Rails 5.2. – MSC Dec 06 '18 at 04:25
  • @CraigWalker - It has been some years, but perhaps it's worth asking: is it safe to call `raw` user inputted json? Would it using `h` instead ben an unacceptable proposition? – BenKoshy Apr 06 '22 at 00:50