Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save pixeltrix/465458 to your computer and use it in GitHub Desktop.

Select an option

Save pixeltrix/465458 to your computer and use it in GitHub Desktop.
From 6fd41cca5c4189e7937307b707574e82802b4dea Mon Sep 17 00:00:00 2001
From: Andrew White <[email protected]>
Date: Tue, 6 Jul 2010 15:32:47 +0100
Subject: [PATCH] Move path prefix to controller requirement so that
recognition and generation of namespaced default routes work
[#5052 state:resolved]
---
actionpack/lib/action_dispatch/routing/mapper.rb | 15 +++++++++++++--
.../lib/action_dispatch/routing/route_set.rb | 6 ++----
actionpack/test/dispatch/routing_test.rb | 3 +++
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 6529cf6..3f4ed0c 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -66,6 +66,17 @@ module ActionDispatch
end
path = normalize_path(path)
+
+ # Rack::Mount doesn't handle namespaced :controller segments so we move
+ # the path prefix to a controller requirement if the path prefix and the
+ # the module match. If they don't match then we are looking at a more
+ # complex situation and we let the end user handle the situation.
+ if path =~ %r{(.+)/:controller} && $1[1..-1] == @scope[:module]
+ before, after = path.split(':controller')
+ path = "/:controller#{after}"
+ (options[:constraints] ||= {}).reverse_merge!(:controller => %r(#{before[1..-2]}/[^/]+))
+ end
+
path_without_format = path.sub(/\(\.:format\)$/, '')
if using_match_shorthand?(path_without_format, options)
@@ -93,7 +104,7 @@ module ActionDispatch
def app
Constraints.new(
- to.respond_to?(:call) ? to : Routing::RouteSet::Dispatcher.new(:defaults => defaults, :module => @scope[:module]),
+ to.respond_to?(:call) ? to : Routing::RouteSet::Dispatcher.new(:defaults => defaults),
blocks,
@set.request_class
)
@@ -899,7 +910,7 @@ module ActionDispatch
collection_name = parent_resource.collection_name
member_name = parent_resource.member_name
name_prefix = "#{name_prefix}_" if name_prefix.present?
- end
+ end
case @scope[:scope_level]
when :collection
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 01a068a..1b1a221 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -14,7 +14,6 @@ module ActionDispatch
def initialize(options={})
@defaults = options[:defaults]
@glob_param = options.delete(:glob)
- @module = options.delete(:module)
@controllers = {}
end
@@ -39,12 +38,11 @@ module ActionDispatch
# we should raise an error in case it's not found, because it usually means
# an user error. However, if the controller was retrieved through a dynamic
# segment, as in :controller(/:action), we should simply return nil and
- # delegate the control back to Rack cascade. Besides, if this is not a default
+ # delegate the control back to Rack cascade. Besides, if this is not a default
# controller, it means we should respect the @scope[:module] parameter.
def controller(params, default_controller=true)
if params && params.key?(:controller)
- controller_param = @module && !default_controller ?
- "#{@module}/#{params[:controller]}" : params[:controller]
+ controller_param = params[:controller]
controller_reference(controller_param)
end
rescue NameError => e
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 463a62c..fa7e10c 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -494,12 +494,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/private/foo'
assert_equal 'private/foo#index', @response.body
+ assert_equal '/private/foo', url_for(:controller => 'private/foo', :action => 'index', :only_path => true)
get '/private/foo/bar'
assert_equal 'private/foo#bar', @response.body
+ assert_equal '/private/foo/bar', url_for(:controller => 'private/foo', :action => 'bar', :only_path => true)
get '/private/foo/bar/1'
assert_equal 'private/foo#bar', @response.body
+ assert_equal '/private/foo/bar/1', url_for(:controller => 'private/foo', :action => 'bar', :id => '1', :only_path => true)
end
end
--
1.7.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment