提交 9dc258d6 编写于 作者: J Joshua Peek

Eager load Partial variable_name and counter_name. Tidy up render_partial_collection.

上级 76df9fa0
......@@ -108,8 +108,7 @@ def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nod
case partial_path
when String, Symbol, NilClass
variable_name, path = partial_pieces(partial_path)
pick_template(path).render_partial(self, variable_name, object_assigns, local_assigns)
pick_template(find_partial_path(partial_path)).render_partial(self, object_assigns, local_assigns)
when ActionView::Helpers::FormBuilder
builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '')
render_partial(builder_partial_path, object_assigns, (local_assigns || {}).merge(builder_partial_path.to_sym => partial_path))
......@@ -130,43 +129,29 @@ def render_partial_collection(partial_path, collection, partial_spacer_template
local_assigns = local_assigns ? local_assigns.clone : {}
spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
_partial_pieces = {}
_paths = {}
_templates = {}
index = 0
collection.map do |object|
_partial_path ||= partial_path || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
variable_name, path = _partial_pieces[_partial_path] ||= partial_pieces(_partial_path)
path = _paths[_partial_path] ||= find_partial_path(_partial_path)
template = _templates[path] ||= pick_template(path)
local_assigns["#{variable_name}_counter".to_sym] = index
local_assigns[:object] = local_assigns[variable_name] = object
local_assigns[as] = object if as
result = template.render_partial(self, variable_name, object, local_assigns)
local_assigns.delete(as)
local_assigns.delete(variable_name)
local_assigns.delete(:object)
local_assigns[template.counter_name] = index
result = template.render_partial(self, object, local_assigns, as)
index += 1
result
end.join(spacer)
end
def partial_pieces(partial_path)
def find_partial_path(partial_path)
if partial_path.include?('/')
variable_name = File.basename(partial_path)
path = "#{File.dirname(partial_path)}/_#{variable_name}"
"#{File.dirname(partial_path)}/_#{File.basename(partial_path)}"
elsif respond_to?(:controller)
variable_name = partial_path
path = "#{controller.class.controller_path}/_#{variable_name}"
"#{controller.class.controller_path}/_#{partial_path}"
else
variable_name = partial_path
path = "_#{variable_name}"
"_#{partial_path}"
end
variable_name = variable_name.sub(/\..*$/, '').to_sym
return variable_name, path
end
end
end
......@@ -7,16 +7,21 @@ def self.included(base)
@@mutex = Mutex.new
end
# NOTE: Exception to earlier notice. Ensure this is called before freeze
def handler
@handler ||= Template.handler_class_for_extension(extension)
end
# NOTE: Exception to earlier notice. Ensure this is called before freeze
def compiled_source
@compiled_source ||= handler.new(nil).compile(self) if handler.compilable?
end
def freeze
# Eager load and freeze memoized methods
handler.freeze
compiled_source.freeze
super
end
def render(view, local_assigns = {})
view._first_render ||= self
view._last_render = self
......
......@@ -3,16 +3,36 @@ module RenderablePartial
# NOTE: The template that this mixin is beening include into is frozen
# So you can not set or modify any instance variables
def variable_name
@variable_name ||= name.gsub(/^_/, '').to_sym
end
def counter_name
@counter_name ||= "#{variable_name}_counter".to_sym
end
def freeze
# Eager load and freeze memoized methods
variable_name.freeze
counter_name.freeze
super
end
def render(view, local_assigns = {})
ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do
super
end
end
def render_partial(view, variable_name, object = nil, local_assigns = {}, as = nil)
object ||= view.controller.instance_variable_get("@#{variable_name}") if view.respond_to?(:controller)
local_assigns[:object] ||= local_assigns[variable_name] ||= object
local_assigns[as] ||= local_assigns[:object] if as
def render_partial(view, object = nil, local_assigns = {}, as = nil)
object ||= local_assigns[:object] ||
local_assigns[variable_name] ||
view.controller.instance_variable_get("@#{variable_name}") if view.respond_to?(:controller)
# Ensure correct object is reassigned to other accessors
local_assigns[:object] = local_assigns[variable_name] = object
local_assigns[as] = object if as
render_template(view, local_assigns)
end
end
......
......@@ -17,19 +17,13 @@ def initialize(template_path, load_paths = [])
end
def freeze
# Eager load memoized methods
format_and_extension
path
path_without_extension
path_without_format_and_extension
source
method_segment
# Eager load memoized methods from Renderable
handler
compiled_source
instance_variables.each { |ivar| ivar.freeze }
# Eager load and freeze memoized methods
format_and_extension.freeze
path.freeze
path_without_extension.freeze
path_without_format_and_extension.freeze
source.freeze
method_segment.freeze
super
end
......@@ -51,12 +45,12 @@ def path_without_format_and_extension
end
def source
@source ||= File.read(@filename)
@source ||= File.read(filename)
end
def method_segment
unless @method_segment
segment = File.expand_path(@filename)
segment = File.expand_path(filename)
segment.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}/, '') if defined?(RAILS_ROOT)
segment.gsub!(/([^a-zA-Z0-9_])/) { $1.ord }
@method_segment = segment
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册