Question

Gon works nicely with Jbuilder. In particular, the documentation tells to use it like this

gon.jbuilder template: 'path/to/template.json.jbuilder'

This works nicely, but I would like to cache the template result so there is no need to re-render the template. Hence, I used render_to_string, like this:

gon.entities = Rails.cache.fetch('entities_json') do
  JSON.parse render_to_string(template: 'path/to/template.json.jbuilder')
end

The method returns the appropriate string, I have to pass it through JSON.parse, otherwise the gon variable stores a double-encoded JSON string. This is annoying, but I don't know how else to solve it.

Unfortunately, this invocation to render_to_string results in the whole HTML page being rendered as a string. The HTML is complete, the gon variables have the expected values, but out of a sudden, the page is not displayed as a HTML anymore in Chrome.

Any idea how to solve this?

Was it helpful?

Solution

Looks like you could now easily do fragment caching with Jbuilder. Here's an example I found in jbuilder's source:

Example:

json.cache! ['v1', @person], :expires_in => 10.minutes do |json|
  json.extract! @person, :name, :age
end

Applying this to your code, we will retain the following code in your controller:

gon.jbuilder template: 'path/to/template.json.jbuilder'

Then inside your jbuilder view, we'll do the fragment caching:

#path/to/template.json.jbuilder
json.cache! ['v1', @model], :expires_in => 10.minutes do |json|
  #your template.json.juilder code in here
end

Let me know if it helps!

OTHER TIPS

There are some issues with render_to_string changing the content_type for subsequent renders. See: https://github.com/rails/rails/issues/14173

Some possible workarounds are

  • Explicitly set the content_type when you call render, e.g. render content_type: text/html
  • Explicitly set the content_type for the response after calling render_to_string. This option might be preferred if you are putting render_to_string in a controller helper method and don't wish to require whoever is calling the helper method to be aware of the weirdness. e.g. response.headers["Content-Type"] = request.format.to_s
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top