From 4dae04896de34114fc2d0043e6484a6a210ecdb4 Mon Sep 17 00:00:00 2001 From: ccocchi Date: Mon, 28 May 2012 10:56:53 +0200 Subject: [PATCH] First implementation of fragment cache --- lib/rabl-rails.rb | 1 + lib/rabl-rails/compiler.rb | 16 ++++++++++++++-- lib/{rabl-fast-json => rabl-rails}/fragment.rb | 17 +++++++++-------- lib/rabl-rails/renderers/base.rb | 6 ++++++ test/compiler_test.rb | 10 ++++++++++ test/fragment_cache_test.rb | 4 ++++ 6 files changed, 44 insertions(+), 10 deletions(-) rename lib/{rabl-fast-json => rabl-rails}/fragment.rb (73%) create mode 100644 test/fragment_cache_test.rb diff --git a/lib/rabl-rails.rb b/lib/rabl-rails.rb index 77c6c4c..b04c068 100644 --- a/lib/rabl-rails.rb +++ b/lib/rabl-rails.rb @@ -6,6 +6,7 @@ require 'active_support/core_ext/class/attribute_accessors' require 'rabl-rails/version' require 'rabl-rails/template' +require 'rabl-rails/fragment' require 'rabl-rails/compiler' require 'rabl-rails/renderer' diff --git a/lib/rabl-rails/compiler.rb b/lib/rabl-rails/compiler.rb index 43976b9..1b86325 100644 --- a/lib/rabl-rails/compiler.rb +++ b/lib/rabl-rails/compiler.rb @@ -6,6 +6,7 @@ module RablRails class Compiler def initialize @glue_count = 0 + @cache_count = 0 end # @@ -124,6 +125,17 @@ module RablRails t = Library.instance.get(path) @template.merge!(t.source) end + + # + # cache key: ->(resource) { |resource| resource.cache_key }, expires_in: 1800 + # + def cache(options = {}, &block) + return unless block_given? + key = options.delete(:key) + source = sub_compile { yield } + @template[:"_cache#{@cache_count}"] = Fragment.new(key, source, options) + @cache_count += 1 + end protected @@ -148,11 +160,11 @@ module RablRails end end - def sub_compile(data) + def sub_compile(data = nil) return {} unless block_given? old_template, @template = @template, {} yield - @template.merge!(:_data => data) + data ? @template.merge!(:_data => data) : @template ensure @template = old_template end diff --git a/lib/rabl-fast-json/fragment.rb b/lib/rabl-rails/fragment.rb similarity index 73% rename from lib/rabl-fast-json/fragment.rb rename to lib/rabl-rails/fragment.rb index 72b9e07..77589f6 100644 --- a/lib/rabl-fast-json/fragment.rb +++ b/lib/rabl-rails/fragment.rb @@ -1,8 +1,7 @@ require 'active_support/cache' -module RablFastJson +module RablRails class Fragment - attr_reader :compiled_source, :options def initialize(key, source, options = {}) @@ -12,16 +11,18 @@ module RablFastJson end def expand_cache_key(data) - @key.call(data) - end - - def fetch_and_render - Rails.cache.fetch(key) + if @key + @key.respond_to?(:call) ? @key.call(data) : @key + else + ActiveSupport::Cache.expand_cache_key(data, 'rabl') + end end end end - +# +# cache key: ->(resource) { |resource| resource.cache_key }, expires_in: 1800 +# # def cache(options = {}, &block) # return unless block_given? # key = options.delete(:key) diff --git a/lib/rabl-rails/renderers/base.rb b/lib/rabl-rails/renderers/base.rb index 6eebe49..8f671d5 100644 --- a/lib/rabl-rails/renderers/base.rb +++ b/lib/rabl-rails/renderers/base.rb @@ -62,6 +62,12 @@ module RablRails else # child object.respond_to?(:each) ? render_collection(object, current_value) : render_resource(object, current_value) end + when Fragment + cache_output = Rails.cache.fetch(value.expand_cache_key(data), value.options) do + data.respond_to?(:each) ? render_collection(data, value.compiled_source) : render_resource(data, value.compiled_source) + end + output.merge!(cache_output) + next output end output[key] = out output diff --git a/test/compiler_test.rb b/test/compiler_test.rb index 944fc56..d83abcc 100644 --- a/test/compiler_test.rb +++ b/test/compiler_test.rb @@ -149,4 +149,14 @@ class CompilerTest < ActiveSupport::TestCase assert_equal({ :user => { :_data => :@user, :id => :id } }, t.source) assert_equal false, t.data end + + test "cache are compiled to fragment" do + t = @compiler.compile_source(%{ + cache do + attributes :name + end + }) + assert_instance_of RablRails::Fragment, t.source[:_cache0] + assert_equal({ :name => :name }, t.source[:_cache0].compiled_source) + end end \ No newline at end of file diff --git a/test/fragment_cache_test.rb b/test/fragment_cache_test.rb new file mode 100644 index 0000000..76532f6 --- /dev/null +++ b/test/fragment_cache_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class FragmentCacheTest < ActiveSupport::TestCase +end \ No newline at end of file