Search code examples
javascriptruby-on-railsrubyjsonjbuilder

Render a Jbuilder template and assign the string to gon


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?


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!