mirror of
https://github.com/github/rails.git
synced 2026-01-27 15:28:00 -05:00
Memoize ActionView::Base pick_template and find_partial_path for rendering duration
This commit is contained in:
@@ -1261,6 +1261,8 @@ module ActionController #:nodoc:
|
|||||||
def template_exempt_from_layout?(template_name = default_template_name)
|
def template_exempt_from_layout?(template_name = default_template_name)
|
||||||
template_name = @template.pick_template(template_name).to_s if @template
|
template_name = @template.pick_template(template_name).to_s if @template
|
||||||
@@exempt_from_layout.any? { |ext| template_name =~ ext }
|
@@exempt_from_layout.any? { |ext| template_name =~ ext }
|
||||||
|
rescue ActionView::MissingTemplate
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_template_name(action_name = self.action_name)
|
def default_template_name(action_name = self.action_name)
|
||||||
|
|||||||
@@ -332,6 +332,9 @@ module ActionView #:nodoc:
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
extend ActiveSupport::Memoizable
|
||||||
|
memoize :pick_template
|
||||||
|
|
||||||
private
|
private
|
||||||
# Renders the template present at <tt>template_path</tt>. The hash in <tt>local_assigns</tt>
|
# Renders the template present at <tt>template_path</tt>. The hash in <tt>local_assigns</tt>
|
||||||
# is made available as local variables.
|
# is made available as local variables.
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ module ActionView
|
|||||||
#
|
#
|
||||||
# As you can see, the <tt>:locals</tt> hash is shared between both the partial and its layout.
|
# As you can see, the <tt>:locals</tt> hash is shared between both the partial and its layout.
|
||||||
module Partials
|
module Partials
|
||||||
|
extend ActiveSupport::Memoizable
|
||||||
|
|
||||||
private
|
private
|
||||||
def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nodoc:
|
def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nodoc:
|
||||||
local_assigns ||= {}
|
local_assigns ||= {}
|
||||||
@@ -129,14 +131,12 @@ module ActionView
|
|||||||
|
|
||||||
local_assigns = local_assigns ? local_assigns.clone : {}
|
local_assigns = local_assigns ? local_assigns.clone : {}
|
||||||
spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
|
spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
|
||||||
_paths = {}
|
|
||||||
_templates = {}
|
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
collection.map do |object|
|
collection.map do |object|
|
||||||
_partial_path ||= partial_path || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
|
_partial_path ||= partial_path || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
|
||||||
path = _paths[_partial_path] ||= find_partial_path(_partial_path)
|
path = find_partial_path(_partial_path)
|
||||||
template = _templates[path] ||= pick_template(path)
|
template = pick_template(path)
|
||||||
local_assigns[template.counter_name] = index
|
local_assigns[template.counter_name] = index
|
||||||
result = template.render_partial(self, object, local_assigns, as)
|
result = template.render_partial(self, object, local_assigns, as)
|
||||||
index += 1
|
index += 1
|
||||||
@@ -153,5 +153,6 @@ module ActionView
|
|||||||
"_#{partial_path}"
|
"_#{partial_path}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
memoize :find_partial_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ module ActionView #:nodoc:
|
|||||||
load_paths = Array(load_paths) + [nil]
|
load_paths = Array(load_paths) + [nil]
|
||||||
load_paths.each do |load_path|
|
load_paths.each do |load_path|
|
||||||
file = [load_path, path].compact.join('/')
|
file = [load_path, path].compact.join('/')
|
||||||
return load_path, file if File.exist?(file)
|
return load_path, file if File.exist?(file) && File.file?(file)
|
||||||
end
|
end
|
||||||
raise MissingTemplate.new(load_paths, path)
|
raise MissingTemplate.new(load_paths, path)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ require 'controller/fake_models'
|
|||||||
uses_mocha 'TestTemplateRecompilation' do
|
uses_mocha 'TestTemplateRecompilation' do
|
||||||
class CompiledTemplatesTest < Test::Unit::TestCase
|
class CompiledTemplatesTest < Test::Unit::TestCase
|
||||||
def setup
|
def setup
|
||||||
@view = ActionView::Base.new(ActionController::Base.view_paths, {})
|
|
||||||
@compiled_templates = ActionView::Base::CompiledTemplates
|
@compiled_templates = ActionView::Base::CompiledTemplates
|
||||||
@compiled_templates.instance_methods.each do |m|
|
@compiled_templates.instance_methods.each do |m|
|
||||||
@compiled_templates.send(:remove_method, m) if m =~ /^_run_/
|
@compiled_templates.send(:remove_method, m) if m =~ /^_run_/
|
||||||
@@ -13,29 +12,33 @@ uses_mocha 'TestTemplateRecompilation' do
|
|||||||
|
|
||||||
def test_template_gets_compiled
|
def test_template_gets_compiled
|
||||||
assert_equal 0, @compiled_templates.instance_methods.size
|
assert_equal 0, @compiled_templates.instance_methods.size
|
||||||
assert_equal "Hello world!", @view.render("test/hello_world.erb")
|
assert_equal "Hello world!", render("test/hello_world.erb")
|
||||||
assert_equal 1, @compiled_templates.instance_methods.size
|
assert_equal 1, @compiled_templates.instance_methods.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
|
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
|
||||||
assert_equal 0, @compiled_templates.instance_methods.size
|
assert_equal 0, @compiled_templates.instance_methods.size
|
||||||
assert_equal "Hello world!", @view.render("test/hello_world.erb")
|
assert_equal "Hello world!", render("test/hello_world.erb")
|
||||||
assert_equal "Hello world!", @view.render("test/hello_world.erb", {:foo => "bar"})
|
assert_equal "Hello world!", render("test/hello_world.erb", {:foo => "bar"})
|
||||||
assert_equal 2, @compiled_templates.instance_methods.size
|
assert_equal 2, @compiled_templates.instance_methods.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns
|
def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns
|
||||||
assert_equal 0, @compiled_templates.instance_methods.size
|
assert_equal 0, @compiled_templates.instance_methods.size
|
||||||
assert_equal "Hello world!", @view.render("test/hello_world.erb")
|
assert_equal "Hello world!", render("test/hello_world.erb")
|
||||||
ActionView::Template.any_instance.expects(:compile!).never
|
ActionView::Template.any_instance.expects(:compile!).never
|
||||||
assert_equal "Hello world!", @view.render("test/hello_world.erb")
|
assert_equal "Hello world!", render("test/hello_world.erb")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compiled_template_will_always_be_recompiled_when_rendered_if_template_is_outside_cache
|
def test_compiled_template_will_be_recompiled_when_rendered_if_template_is_outside_cache
|
||||||
assert_equal 0, @compiled_templates.instance_methods.size
|
assert_equal 0, @compiled_templates.instance_methods.size
|
||||||
assert_equal "Hello world!", @view.render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
|
assert_equal "Hello world!", render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
|
||||||
ActionView::Template.any_instance.expects(:compile!).times(3)
|
assert_equal 1, @compiled_templates.instance_methods.size
|
||||||
3.times { assert_equal "Hello world!", @view.render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb") }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def render(*args)
|
||||||
|
ActionView::Base.new(ActionController::Base.view_paths, {}).render(*args)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user