Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache root #370

Merged
merged 8 commits into from
Nov 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions lib/jbuilder/jbuilder_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@ def cache!(key=nil, options={})
end
end

# Caches the json structure at the root using a string rather than the hash structure. This is considerably
# faster, but the drawback is that it only works, as the name hints, at the root. So you cannot
# use this approach to cache deeper inside the hierarchy, like in partials or such. Continue to use #cache! there.
#
# Example:
#
# json.cache_root! @person do
# json.extract! @person, :name, :age
# end
#
# # json.extra 'This will not work either, the root must be exclusive'
def cache_root!(key=nil, options={})
if @context.controller.perform_caching
raise "cache_root! can't be used after JSON structures have been defined" if @attributes.present?

@cached_root = _cache_fragment_for([ :root, key ], options) { yield; target! }
else
yield
end
end

# Conditionally caches the json depending in the condition given as first parameter. Has the same
# signature as the `cache` helper method in `ActionView::Helpers::CacheHelper` and so can be used in
# the same way.
Expand All @@ -55,6 +76,10 @@ def cache_if!(condition, *args)
condition ? cache!(*args, &::Proc.new) : yield
end

def target!
@cached_root || super
end

def array!(collection = [], *args)
options = args.first

Expand Down
29 changes: 29 additions & 0 deletions test/jbuilder_template_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,35 @@ def assert_collection_rendered(result, context = nil)
JBUILDER
end

test "caching root structure" do
undef_context_methods :fragment_name_with_digest, :cache_fragment_name

cache_miss_result = jbuild <<-JBUILDER
json.cache_root! "cachekey" do
json.name "Miss"
end
JBUILDER

cache_hit_result = jbuild <<-JBUILDER
json.cache_root! "cachekey" do
json.name "Hit"
end
JBUILDER

assert_equal cache_miss_result, cache_hit_result
end

test "failing to cache root after attributes have been defined" do
assert_raises ActionView::Template::Error, "cache_root! can't be used after JSON structures have been defined" do
jbuild <<-JBUILDER
json.name "Kaboom"
json.cache_root! "cachekey" do
json.name "Miss"
end
JBUILDER
end
end

test "does not perform caching when controller.perform_caching is false" do
controller.perform_caching = false

Expand Down