diff options
author | José Valim <jose.valim@gmail.com> | 2009-12-02 22:29:34 -0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-12-02 22:29:34 -0200 |
commit | 6e55b32e98fcaad82184d2e21ee611a3465e4b20 (patch) | |
tree | e316b8ca72f2bef50668c222400a159b36fbc090 /actionpack/lib/action_dispatch/routing | |
parent | c2e97cb410d759f383d29920165abdbf4b70e019 (diff) | |
parent | 399909b11c094ab32542d300c72940b1b263b8e6 (diff) | |
download | rails-6e55b32e98fcaad82184d2e21ee611a3465e4b20.tar.gz rails-6e55b32e98fcaad82184d2e21ee611a3465e4b20.tar.bz2 rails-6e55b32e98fcaad82184d2e21ee611a3465e4b20.zip |
Merge branch 'master' of git://github.com/rails/rails
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
-rw-r--r-- | actionpack/lib/action_dispatch/routing/deprecated_mapper.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 63 |
3 files changed, 61 insertions, 8 deletions
diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb index dd76391870..8ce6b2f6d5 100644 --- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb +++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb @@ -113,7 +113,7 @@ module ActionDispatch end end - requirements[:controller] ||= Routing.controller_constraints + requirements[:controller] ||= @set.controller_constraints if defaults[:controller] defaults[:action] ||= 'index' @@ -175,7 +175,7 @@ module ActionDispatch optional = false elsif segment =~ /^:(\w+)$/ if defaults.has_key?($1.to_sym) - defaults.delete($1.to_sym) + defaults.delete($1.to_sym) if defaults[$1.to_sym].nil? else optional = false end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 34d75e55b6..400039353c 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -383,7 +383,7 @@ module ActionDispatch constraints.reject! { |k, v| segment_keys.include?(k.to_s) } conditions.merge!(constraints) - requirements[:controller] ||= Routing.controller_constraints + requirements[:controller] ||= @set.controller_constraints if via = options[:via] via = Array(via).map { |m| m.to_s.upcase } diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 79e15edeaa..a8073c2105 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -27,10 +27,13 @@ module ActionDispatch end end + unless controller = controller(params) + return [417, {}, []] + end + if env['action_controller.recognize'] [200, {}, params] else - controller = controller(params) controller.action(params[:action]).call(env) end end @@ -41,6 +44,8 @@ module ActionDispatch controller = "#{params[:controller].camelize}Controller" ActiveSupport::Inflector.constantize(controller) end + rescue NameError + nil end def merge_default_action!(params) @@ -197,10 +202,11 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes, :configuration_files + attr_accessor :routes, :named_routes, :configuration_files, :controller_paths def initialize self.configuration_files = [] + self.controller_paths = [] self.routes = [] self.named_routes = NamedRouteCollection.new @@ -247,7 +253,7 @@ module ActionDispatch def load! # Clear the controller cache so we may discover new ones - Routing.clear_controller_cache! + @controller_constraints = nil load_routes! end @@ -292,6 +298,37 @@ module ActionDispatch routes_changed_at end + CONTROLLER_REGEXP = /[_a-zA-Z0-9]+/ + + def controller_constraints + @controller_constraints ||= begin + source = controller_namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" } + source << CONTROLLER_REGEXP.source + Regexp.compile(source.sort.reverse.join('|')) + end + end + + def controller_namespaces + namespaces = Set.new + + # Find any nested controllers already in memory + ActionController::Base.subclasses.each do |klass| + controller_name = klass.underscore + namespaces << controller_name.split('/')[0...-1].join('/') + end + + # Find namespaces in controllers/ directory + controller_paths.each do |load_path| + load_path = File.expand_path(load_path) + Dir["#{load_path}/**/*_controller.rb"].collect do |path| + namespaces << File.dirname(path).sub(/#{load_path}\/?/, '') + end + end + + namespaces.delete('') + namespaces + end + def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil) route = Route.new(app, conditions, requirements, defaults, name) @set.add_route(*route) @@ -374,7 +411,8 @@ module ActionDispatch end recall[:action] = options.delete(:action) if options[:action] == 'index' - parameterize = lambda { |name, value| + opts = {} + opts[:parameterize] = lambda { |name, value| if name == :controller value elsif value.is_a?(Array) @@ -384,7 +422,22 @@ module ActionDispatch end } - path = @set.url(named_route, options, recall, :parameterize => parameterize) + unless result = @set.generate(:path_info, named_route, options, recall, opts) + raise ActionController::RoutingError, "No route matches #{options.inspect}" + end + + uri, params = result + params.each do |k, v| + if v + params[k] = v + else + params.delete(k) + end + end + + uri << "?#{params.to_query}" if uri && params.any? + path = uri + if path && method == :generate_extras uri = URI(path) extras = uri.query ? |