aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/routing
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2009-12-02 22:29:34 -0200
committerJosé Valim <jose.valim@gmail.com>2009-12-02 22:29:34 -0200
commit6e55b32e98fcaad82184d2e21ee611a3465e4b20 (patch)
treee316b8ca72f2bef50668c222400a159b36fbc090 /actionpack/lib/action_dispatch/routing
parentc2e97cb410d759f383d29920165abdbf4b70e019 (diff)
parent399909b11c094ab32542d300c72940b1b263b8e6 (diff)
downloadrails-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.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb63
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 ?