public
Created

Poor man's caching for Jbuilder

  • Download Gist
_user.json.jbuilder
1 2
# app/views/users/_user.json.jbuilder
json.(user, :id, :name, :age, :gender)
application_controller.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
class ApplicationController < ActionController::Base
protect_from_forgery
 
def cached_jbuilder(obj, opts = {})
cache_key = (opts[:cache_key_prefix] || []) + Array.wrap(obj)
cached = read_fragment(cache_key)
 
if cached
out = view_context.raw cached
elsif obj.is_a?(Array)
out = ""
obj.each_index do |i|
is_last = (obj.length - 1 == i)
out += cached_jbuilder(obj[i], opts) + (!is_last ? "," : "")
end
out = "[#{out}]"
write_fragment cache_key, out
out
else
out = view_context.raw render_to_string partial: obj, locals: { obj.class.to_s.tableize.to_sym => obj }
write_fragment cache_key, out
out
end
view_context.raw out
end
 
end
index.json.erb
HTML+ERB
1 2
<% # app/views/users/index.json.erb -%>
{"users":<%= controller.cached_jbuilder @users -%>}

The idea behind this is to start building the JSON output through an ERB template. We can then easily use the caching helpers to partially or entirely cache the resulting JSON.

In this example, if @users is populated with 3 records when we render index.json.erb, a total of 4 cache keys will be created: 3 JSON string representations of each user, and 1 JSON string containing all 3 users in an array. If one user changes, the array cache is busted, as well as the cache for the record that has changed.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.