aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb27
-rw-r--r--actionpack/lib/action_dispatch/routing/route.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb4
-rw-r--r--actionpack/test/dispatch/mount_test.rb36
4 files changed, 61 insertions, 10 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 7a33259054..e6c563d7b7 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,5 +1,3 @@
-require "active_support/core_ext/hash/except"
-
module ActionDispatch
module Routing
class Mapper
@@ -38,7 +36,7 @@ module ActionDispatch
end
def to_route
- [ app, conditions, requirements, defaults, @options[:as] ]
+ [ app, conditions, requirements, defaults, @options[:as], @options[:anchor] ]
end
private
@@ -66,7 +64,7 @@ module ActionDispatch
# match "account/overview"
def using_match_shorthand?(args, options)
- args.present? && options.except(:via).empty? && !args.first.include?(':')
+ args.present? && options.except(:via, :anchor).empty? && !args.first.include?(':')
end
def normalize_path(path)
@@ -87,7 +85,7 @@ module ActionDispatch
end
def requirements
- @requirements ||= (@options[:constraints] || {}).tap do |requirements|
+ @requirements ||= returning(@options[:constraints] || {}) do |requirements|
requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints]
@options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) }
end
@@ -176,7 +174,8 @@ module ActionDispatch
end
def match(*args)
- @set.add_route(*Mapping.new(@set, @scope, args).to_route)
+ mapping = Mapping.new(@set, @scope, args).to_route
+ @set.add_route(*mapping)
self
end
end
@@ -295,6 +294,7 @@ module ActionDispatch
options = args.extract_options!
options = (@scope[:options] || {}).merge(options)
+ options[:anchor] = true unless options.key?(:anchor)
if @scope[:name_prefix] && !options[:as].blank?
options[:as] = "#{@scope[:name_prefix]}_#{options[:as]}"
@@ -538,6 +538,21 @@ module ActionDispatch
end
end
+ def mount(app, options = nil)
+ if options
+ path = options.delete(:at)
+ else
+ options = app
+ app, path = options.find { |k, v| k.respond_to?(:call) }
+ options.delete(app) if app
+ end
+
+ raise "A rack application must be specified" unless path
+
+ match(path, options.merge(:to => app, :anchor => false))
+ self
+ end
+
def match(*args)
options = args.extract_options!
diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb
index e6e44d3546..6f37eadd6b 100644
--- a/actionpack/lib/action_dispatch/routing/route.rb
+++ b/actionpack/lib/action_dispatch/routing/route.rb
@@ -4,7 +4,7 @@ module ActionDispatch
attr_reader :app, :conditions, :defaults, :name
attr_reader :path, :requirements
- def initialize(app, conditions = {}, requirements = {}, defaults = {}, name = nil)
+ def initialize(app, conditions, requirements, defaults, name, anchor)
@app = app
@defaults = defaults
@name = name
@@ -17,7 +17,7 @@ module ActionDispatch
if path = conditions[:path_info]
@path = path
- conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS)
+ conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS, anchor)
end
@conditions = conditions.inject({}) { |h, (k, v)|
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 5c246d8781..550e54e955 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -293,8 +293,8 @@ module ActionDispatch
routes.empty?
end
- def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil)
- route = Route.new(app, conditions, requirements, defaults, name)
+ def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
+ route = Route.new(app, conditions, requirements, defaults, name, anchor)
@set.add_route(*route)
named_routes[name] = route if name
routes << route
diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb
new file mode 100644
index 0000000000..f89e5fda07
--- /dev/null
+++ b/actionpack/test/dispatch/mount_test.rb
@@ -0,0 +1,36 @@
+require 'abstract_unit'
+
+class TestRoutingMount < ActionDispatch::IntegrationTest
+ SprocketsApp = lambda { |env|
+ [200, {"Content-Type" => "text/html"}, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]]
+ }
+
+ Router = ActionDispatch::Routing::RouteSet.new
+ Router.draw do
+ mount SprocketsApp, :at => "/sprockets"
+ mount SprocketsApp => "/shorthand"
+
+ scope "/its_a" do
+ mount SprocketsApp, :at => "/sprocket"
+ end
+ end
+
+ def app
+ Router
+ end
+
+ def test_mounting_sets_script_name
+ get "/sprockets/omg"
+ assert_equal "/sprockets -- /omg", response.body
+ end
+
+ def test_mounting_works_with_scope
+ get "/its_a/sprocket/omg"
+ assert_equal "/its_a/sprocket -- /omg", response.body
+ end
+
+ def test_mounting_with_shorthand
+ get "/shorthand/omg"
+ assert_equal "/shorthand -- /omg", response.body
+ end
+end \ No newline at end of file