From d6bac046922fcee05366d26d75349dde70d25f6b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 17 May 2016 11:28:40 -0700 Subject: keep layouts + locals from bloating the cache Using locals will cause layouts to be cached multiple times in the template cache. This commit removes locals from consideration when looking up the layout. --- .../lib/action_view/renderer/template_renderer.rb | 6 +++--- actionview/lib/action_view/template/resolver.rb | 17 +++++++++++++++++ actionview/test/actionpack/abstract/layouts_test.rb | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb index 9d15bbfca7..1d6afb90fe 100644 --- a/actionview/lib/action_view/renderer/template_renderer.rb +++ b/actionview/lib/action_view/renderer/template_renderer.rb @@ -84,13 +84,13 @@ module ActionView when String begin if layout =~ /^\// - with_fallbacks { find_template(layout, nil, false, keys, details) } + with_fallbacks { find_template(layout, nil, false, [], details) } else - find_template(layout, nil, false, keys, details) + find_template(layout, nil, false, [], details) end rescue ActionView::MissingTemplate all_details = @details.merge(:formats => @lookup_context.default_formats) - raise unless template_exists?(layout, nil, false, keys, all_details) + raise unless template_exists?(layout, nil, false, [], all_details) end when Proc resolve_layout(layout.call(formats), keys, formats) diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index c5e69b1833..bf68e93c58 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -88,6 +88,23 @@ module ActionView @query_cache.clear end + # Get the cache size. Do not call this + # method. This method is not guaranteed to be here ever. + def size # :nodoc: + size = 0 + @data.each_value do |v1| + v1.each_value do |v2| + v2.each_value do |v3| + v3.each_value do |v4| + size += v4.size + end + end + end + end + + size + @query_cache.size + end + private def canonical_no_templates(templates) diff --git a/actionview/test/actionpack/abstract/layouts_test.rb b/actionview/test/actionpack/abstract/layouts_test.rb index 8c80a2d2cf..72765dc7f5 100644 --- a/actionview/test/actionpack/abstract/layouts_test.rb +++ b/actionview/test/actionpack/abstract/layouts_test.rb @@ -224,6 +224,25 @@ module AbstractControllerTests assert_equal "With String hello less than 3 bar", controller.response_body end + test "cache should not grow when locals change for a string template" do + cache = WithString.view_paths.paths.first.instance_variable_get(:@cache) + + controller = WithString.new + controller.process(:index) # heat the cache + + size = cache.size + + 10.times do |x| + controller = WithString.new + controller.define_singleton_method :index do + render :template => ActionView::Template::Text.new("Hello string!"), :locals => { :"x#{x}" => :omg } + end + controller.process(:index) + end + + assert_equal size, cache.size + end + test "when layout is specified as a string, render with that layout" do controller = WithString.new controller.process(:index) -- cgit v1.2.3