Permalink
Browse files

Merge pull request #66 from rgarver/feature/cache-with-partials

The new cache! method doesn't allow partial! calls to be nested
  • Loading branch information...
2 parents 69a4d47 + e303a91 commit 3a7a846a70e5b7e23f3deb7a7904db7356afec80 @dhh dhh committed Sep 25, 2012
Showing with 87 additions and 87 deletions.
  1. +0 −26 lib/jbuilder.rb
  2. +25 −0 lib/jbuilder_template.rb
  3. +62 −0 test/jbuilder_template_test.rb
  4. +0 −61 test/jbuilder_test.rb
View
@@ -215,37 +215,11 @@ def target!
::MultiJson.encode @attributes
end
- # Caches the json constructed within the block passed. Has the same signature as the `cache` helper
- # method in `ActionView::Helpers::CacheHelper` and so can be used in the same way.
- #
- # Example:
- #
- # json.cache! ['v1', @person], :expires_in => 10.minutes do |json|
- # json.extract! @person, :name, :age
- # end
- def cache!(key=nil, options={}, &block)
- cache_key = ::ActiveSupport::Cache.expand_cache_key(key.is_a?(::Hash) ? url_for(key).split("://").last : key, :jbuilder)
- value = ::Rails.cache.fetch(cache_key, options) do
- jb = ::Jbuilder.new
- yield jb
- jb.attributes!
- end
-
- if value.is_a?(::Array)
- array! value
- else
- value.each do |k, v|
- set! k, v
- end
- end
- end
-
protected
def _set_value(key, value)
@attributes[@key_formatter.format(key)] = value
end
-
private
def method_missing(method, value = nil, *args)
result = if ::Kernel.block_given?
View
@@ -14,6 +14,31 @@ def partial!(options, locals = {})
@context.render(options, locals.merge(:json => self))
end
end
+
+ # Caches the json constructed within the block passed. Has the same signature as the `cache` helper
+ # method in `ActionView::Helpers::CacheHelper` and so can be used in the same way.
+ #
+ # Example:
+ #
+ # json.cache! ['v1', @person], :expires_in => 10.minutes do |json|
+ # json.extract! @person, :name, :age
+ # end
+ def cache!(key=nil, options={}, &block)
+ cache_key = ::ActiveSupport::Cache.expand_cache_key(key.is_a?(::Hash) ? url_for(key).split("://").last : key, :jbuilder)
+ value = ::Rails.cache.fetch(cache_key, options) do
+ jb = ::JbuilderTemplate.new(@context)
+ yield jb
+ jb.attributes!
+ end
+
+ if value.is_a?(::Array)
+ array! value
+ else
+ value.each do |k, v|
+ set! k, v
+ end
+ end
+ end
end
class JbuilderHandler
@@ -1,9 +1,32 @@
require 'test/unit'
require 'action_view'
require 'action_view/testing/resolvers'
+require 'active_support/cache'
require 'jbuilder'
+module Rails
+ class Cache
+ def initialize
+ @cache = {}
+ end
+
+ def write(k, v, opt={})
+ @cache[k] = v
+ end
+
+ def read(k, opt={})
+ @cache[k]
+ end
+
+ def fetch(k, opt={}, &block)
+ @cache[k] || @cache[k] = block.call
+ end
+ end
+
+ def self.cache; @cache ||= Cache.new; end
+end
+
class JbuilderTemplateTest < ActionView::TestCase
def partials
{ "_partial.json.jbuilder" => 'json.content "hello"' }
@@ -53,4 +76,43 @@ def render_jbuilder(source)
assert_equal "hello", MultiJson.load(json)["content"]
end
+
+ test "fragment caching a JSON object" do
+ json = render_jbuilder <<-JBUILDER
+ json.cache!("cachekey") do |json|
+ json.name "Cache"
+ end
+ JBUILDER
+
+ Rails.cache.read("jbuilder/cachekey").tap do |parsed|
+ assert_equal "Cache", parsed['name']
+ end
+ end
+
+ test "fragment caching deserializes a JSON object" do
+ Rails.cache.write("jbuilder/cachekey", {'name' => "Something"})
+ json = render_jbuilder <<-JBUILDER
+ json.cache!("cachekey") do |json|
+ json.name "Cache"
+ end
+ JBUILDER
+
+ JSON.parse(json).tap do |parsed|
+ assert_equal "Something", parsed['name']
+ end
+ end
+
+ test "fragment caching deserializes an array" do
+ Rails.cache.write("jbuilder/cachekey", ["a", "b", "c"])
+ json = render_jbuilder <<-JBUILDER
+ json.cache!("cachekey") do |json|
+ json.array! ['1', '2', '3']
+ end
+ JBUILDER
+
+ JSON.parse(json).tap do |parsed|
+ assert_equal ["a", "b", "c"], parsed
+ end
+ end
+
end
View
@@ -1,32 +1,9 @@
require 'test/unit'
require 'active_support/test_case'
-require 'active_support/cache'
require 'active_support/inflector'
require 'jbuilder'
-module Rails
- class Cache
- def initialize
- @cache = {}
- end
-
- def write(k, v, opt={})
- @cache[k] = v
- end
-
- def read(k, opt={})
- @cache[k]
- end
-
- def fetch(k, opt={}, &block)
- @cache[k] || @cache[k] = block.call
- end
- end
-
- def self.cache; @cache ||= Cache.new; end
-end
-
class JbuilderTest < ActiveSupport::TestCase
test "single key" do
json = Jbuilder.encode do |json|
@@ -434,42 +411,4 @@ def empty?
assert_equal [], Jbuilder.send(:class_variable_get, "@@key_formatter").instance_variable_get("@cache").keys
end
- test "fragment caching a JSON object" do
- json = Jbuilder.encode do |json|
- json.cache!("cachekey") do |json|
- json.name "Cache"
- end
- end
-
- Rails.cache.read("jbuilder/cachekey").tap do |parsed|
- assert_equal "Cache", parsed['name']
- end
- end
-
- test "fragment caching deserializes a JSON object" do
- Rails.cache.write("jbuilder/cachekey", {'name' => "Something"})
- json = Jbuilder.encode do |json|
- json.cache!("cachekey") do |json|
- json.name "Cache"
- end
- end
-
- JSON.parse(json).tap do |parsed|
- assert_equal "Something", parsed['name']
- end
- end
-
- test "fragment caching deserializes an array" do
- Rails.cache.write("jbuilder/cachekey", ["a", "b", "c"])
- json = Jbuilder.encode do |json|
- json.cache!("cachekey") do |json|
- json.array! ['1', '2', '3']
- end
- end
-
- JSON.parse(json).tap do |parsed|
- assert_equal ["a", "b", "c"], parsed
- end
- end
-
end

0 comments on commit 3a7a846

Please sign in to comment.