From 4945d8223964d4ccb3c0a0f4107f15ae1c6c4a09 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Mon, 10 Aug 2009 02:54:17 -0400 Subject: Further experimentation. Was able to cut the cost of rendering 100 partials in a collection in half. To discuss: What are the desired semantics (if any) for layouts in a collection. There are no tests for it at present, and I'm not sure if it's needed at all. Deprecated on this branch: `object` pointing at the current object in partials. You can still use the partial name, or use :as to achieve the same thing. This is obviously up for discussion. --- actionpack/lib/action_view/render/partials.rb | 49 ++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'actionpack/lib/action_view/render') diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 64f08c447d..2aa3bd7db8 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -207,9 +207,7 @@ module ActionView end def render_collection - # Even if no template is rendered, this will ensure that the MIME type - # for the empty response is the same as the provided template - @options[:_template] = default_template = find_template + @options[:_template] = template = find_template return nil if collection.blank? @@ -217,15 +215,48 @@ module ActionView spacer = find_template(@options[:spacer_template]).render(@view, @locals) end - segments = [] + result = template ? collection_with_template(template) : collection_without_template + result.join(spacer) + end + + def collection_with_template(template) + options = @options + + segments, locals, as = [], @locals, options[:as] + + [].tap do |segments| + variable_name = template.variable_name + counter_name = template.counter_name + locals[counter_name] = -1 - collection.each_with_index do |object, index| - template = default_template || find_template(partial_path(object)) - @locals[template.counter_name] = index - segments << render_template(template, object) + collection.each do |object| + locals[counter_name] += 1 + locals[variable_name] = object + locals[as] = object if as + + segments << template.render(@view, locals) + end end + end - segments.join(spacer) + def collection_without_template + options = @options + + segments, locals, as = [], @locals, options[:as] + index, template = -1, nil + + [].tap do |segments| + collection.each do |object| + template = find_template(partial_path(object)) + locals[template.counter_name] = (index += 1) + locals[template.variable_name] = object + locals[as] = object if as + + segments << template.render(@view, locals) + end + + @options[:_template] = template + end end def render_template(template, object = @object) -- cgit v1.2.3