From 199e750d46c04970b5e7684998d09405648ecbd4 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Tue, 10 Feb 2009 12:09:49 -0600 Subject: Fix some edge cases when the same template is called with different local assigns Signed-off-by: Joshua Peek --- actionpack/lib/action_view/renderable.rb | 30 +++++++++++++++++++++++++++++- actionpack/lib/action_view/template.rb | 23 +++++++++++------------ 2 files changed, 40 insertions(+), 13 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index c127bb25d6..16cdd0162e 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -16,8 +16,18 @@ module ActionView memoize :handler def compiled_source + @compiled_at = Time.now handler.call(self) end + memoize :compiled_source + + def compiled_at + @compiled_at + end + + def defined_at + @defined_at ||= {} + end def method_name_without_locals ['_run', extension, method_segment].compact.join('_') @@ -61,8 +71,12 @@ module ActionView def compile(local_assigns) render_symbol = method_name(local_assigns) - if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile? + if self.is_a?(InlineTemplate) compile!(render_symbol, local_assigns) + else + if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile?(render_symbol) + recompile!(render_symbol, local_assigns) + end end end @@ -79,6 +93,7 @@ module ActionView begin ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) + defined_at[render_symbol] = Time.now if respond_to?(:reloadable?) && reloadable? rescue Errno::ENOENT => e raise e # Missing template file, re-raise for Base to rescue rescue Exception => e # errors from template code @@ -91,5 +106,18 @@ module ActionView raise ActionView::TemplateError.new(self, {}, e) end end + + def recompile?(render_symbol) + !cached? || redefine?(render_symbol) || stale? + end + + def recompile!(render_symbol, local_assigns) + compiled_source(:reload) if compiled_at.nil? || compiled_at < mtime + compile!(render_symbol, local_assigns) + end + + def redefine?(render_symbol) + compiled_at && defined_at[render_symbol] && compiled_at > defined_at[render_symbol] + end end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index ee1b9f2886..f2d3998d16 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -7,7 +7,9 @@ module ActionView #:nodoc: def initialize(path) raise ArgumentError, "path already is a Path class" if path.is_a?(Path) @path = path.freeze + end + def load! @paths = {} templates_in_path do |template| load_template(template) @@ -44,6 +46,7 @@ module ActionView #:nodoc: # etc. A format must be supplied to match a formated file. +hello/index+ # will never match +hello/index.html.erb+. def [](path) + load! if @paths.nil? @paths[path] || find_template(path) end @@ -197,26 +200,22 @@ module ActionView #:nodoc: end def stale? - !frozen? && mtime < mtime(:reload) + reloadable? && (mtime < mtime(:reload)) end def load! reloadable? ? memoize_all : freeze end - private - def cached? - Base.cache_template_loading || ActionController::Base.allow_concurrency - end - - def reloadable? - !cached? - end + def reloadable? + !(Base.cache_template_loading || ActionController::Base.allow_concurrency) + end - def recompile? - reloadable? ? stale? : false - end + def cached? + ActionController::Base.perform_caching || !reloadable? + end + private def valid_extension?(extension) !Template.registered_template_handler(extension).nil? end -- cgit v1.2.3