From 8ff44631939fd9220f03f9b18a687cbd040220e3 Mon Sep 17 00:00:00 2001 From: Nicholas Seckar Date: Mon, 13 Mar 2006 15:54:33 +0000 Subject: Simplify controller_path Cache File.directory? calls to avoid filesystem calls when using layouts git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3861 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/CHANGELOG | 4 ++++ actionpack/lib/action_controller/base.rb | 8 +------- actionpack/lib/action_controller/layout.rb | 25 ++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index aa1ddd1a08..8beff49f54 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Avoid hitting the filesystem when using layouts by using a File.directory? cache. [Stefan Kaes, Nicholas Seckar] + +* Simplify ActionController::Base#controller_path [Nicholas Seckar] + * Added simple alert() notifications for RJS exceptions when config.action_view.debug_rjs = true. [Sam Stephenson] * Added :content_type option to render, so you can change the content type on the fly [DHH]. Example: render :action => "atom.rxml", :content_type => "application/atom+xml" diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index bcfea86ac4..afb17d7655 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -348,13 +348,7 @@ module ActionController #:nodoc: # Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat". def controller_path - unless @controller_path - components = self.name.to_s.split('::') - components[-1] = $1 if /^(.*)Controller$/ =~ components.last - @controller_path = components.map { |name| name.underscore }.join('/') - end - - @controller_path + @controller_path ||= name.gsub(/Controller$/, '').underscore end # Return an array containing the names of public methods that have been marked hidden from the action processor. diff --git a/actionpack/lib/action_controller/layout.rb b/actionpack/lib/action_controller/layout.rb index 66438d277e..fdee677bbb 100644 --- a/actionpack/lib/action_controller/layout.rb +++ b/actionpack/lib/action_controller/layout.rb @@ -192,6 +192,12 @@ module ActionController #:nodoc: def normalize_conditions(conditions) conditions.inject({}) {|hash, (key, value)| hash.merge(key => [value].flatten.map {|action| action.to_s})} end + + def layout_directory_exists_cache + @@layout_directory_exists_cache ||= Hash.new do |h, dirname| + h[dirname] = File.directory? dirname + end + end end # Returns the name of the active layout. If the layout was specified as a method reference (through a symbol), this method @@ -202,16 +208,21 @@ module ActionController #:nodoc: layout = passed_layout || self.class.read_inheritable_attribute("layout") active_layout = case layout + when String then layout when Symbol then send(layout) when Proc then layout.call(self) - when String then layout end # Explicitly passed layout names with slashes are looked up relative to the template root, # but auto-discovered layouts derived from a nested controller will contain a slash, though be relative # to the 'layouts' directory so we have to check the file system to infer which case the layout name came from. - nested_controller = File.directory?(File.dirname(File.join(self.class.template_root, 'layouts', active_layout))) if active_layout - active_layout.include?('/') && !nested_controller ? active_layout : "layouts/#{active_layout}" if active_layout + if active_layout + if active_layout.include?('/') && ! layout_directory?(active_layout) + active_layout + else + "layouts/#{active_layout}" + end + end end def render_with_a_layout(options = nil, deprecated_status = nil, deprecated_layout = nil, &block) #:nodoc: @@ -280,5 +291,13 @@ module ActionController #:nodoc: true end end + + # Does a layout directory for this class exist? + # we cache this info in a class level hash + def layout_directory?(layout_name) + template_path = File.join(self.class.view_root, 'layouts', layout_name) + dirname = File.dirname(template_path) + self.class.send(:layout_directory_exists_cache)[dirname] + end end end -- cgit v1.2.3