Permalink
Browse files

add build caching with the cache_all_output configuration

* all objects within a collection is cached
* all calls to builder.build are cached so this includes
  anything using object_to_hash (child, glue, and partial)
* added information to README
  • Loading branch information...
1 parent b645f60 commit 36f1e2a0894f4684f1dfe3e00a4280a901c8cb14 @databyte databyte committed with Mar 15, 2012
Showing with 47 additions and 1 deletion.
  1. +5 −0 README.md
  2. +18 −0 fixtures/rails3/test/functional/posts_controller_test.rb
  3. +22 −1 lib/rabl/builder.rb
  4. +2 −0 lib/rabl/configuration.rb
View
5 README.md
@@ -98,6 +98,7 @@ RABL is intended to require little to no configuration to get working. This is t
# config/initializers/rabl_init.rb
Rabl.configure do |config|
# Commented as these are defaults
+ # config.cache_all_output = false
# config.cache_sources = false
# config.json_engine = nil # Any multi\_json engines
# config.msgpack_engine = nil # Defaults to ::MessagePack
@@ -120,6 +121,10 @@ output if the incoming request has a 'callback' parameter.
If `cache_sources` is set to `true`, template lookups will be cached for improved performance.
The cache can be reset manually by running `Rabl.reset_source_cache!` within your application.
+If `cache_all_output` is set to `true` then every template including each individual template used as part of a collection will be cached separately.
+Additionally, anything within child, glue and partial will also be cached separately.
+To cache a single template once, see the section titled Caching below.
+
Note that the `json_engine` option uses the [multi_json](http://intridea.com/2010/6/14/multi-json-the-swappable-json-handler) intelligent engine
defaults so in most cases you **don't need to configure this** directly. If you wish to use yajl as
the primary JSON encoding engine simply add that to your Gemfile:
View
18 fixtures/rails3/test/functional/posts_controller_test.rb
@@ -7,6 +7,8 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
end
+require 'ruby-debug'
+
context "PostsController" do
helper(:json_output) { JSON.parse(last_response.body) }
@@ -138,4 +140,20 @@
asserts(:body).equals { cache_hit }
end
+ context "cache_all_output" do
+ helper(:cache_hit) do |key|
+ Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, nil], :rabl_build))
+ end
+
+ setup do
+ mock(ActionController::Base).perform_caching.any_number_of_times { true }
+ Rabl.configuration.cache_all_output = true
+ get "/posts"
+ end
+
+ asserts("contains cache hits per object (posts by title)") do
+ json_output['articles'].map { |o| o["article"]["title"] }
+ end.equals { @posts.map{ |p| cache_hit(p)[:title] } }
+ end
+
end
View
23 lib/rabl/builder.rb
@@ -15,7 +15,10 @@ def initialize(options={}, &block)
# build(@user, :format => "json", :attributes => { ... }, :root_name => "user")
def build(object, options={})
@_object = object
- compile_hash(options)
+
+ cache_results do
+ compile_hash(options)
+ end
end
protected
@@ -118,5 +121,23 @@ def resolve_condition(options)
result = options[:unless] == false || (options[:unless].respond_to?(:call) && !options[:unless].call(@_object)) if options.has_key?(:unless)
result
end
+
+ private
+
+ def cache_configured?
+ defined?(Rails) && ActionController::Base.perform_caching &&
+ Rabl.configuration.cache_all_output
+ end
+
+ def cache_results(&block)
+ if cache_configured? && @_object.respond_to?(:cache_key)
+ Rails.cache.fetch(
+ ActiveSupport::Cache.expand_cache_key([@_object, @options[:root_name]], :rabl_build),
+ nil,
+ &block)
+ else
+ yield
+ end
+ end
end
end
View
2 lib/rabl/configuration.rb
@@ -35,6 +35,7 @@ class Configuration
attr_writer :plist_engine
attr_writer :xml_options
attr_accessor :cache_sources
+ attr_accessor :cache_all_output
DEFAULT_XML_OPTIONS = { :dasherize => true, :skip_types => false }
@@ -53,6 +54,7 @@ def initialize
@plist_engine = nil
@xml_options = {}
@cache_sources = false
+ @cache_all_output = false
end
# @param [Symbol, String, #encode] engine_name The name of a JSON engine,

0 comments on commit 36f1e2a

Please sign in to comment.