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