mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Add support for mount RackApp, :at => "/sprockets" with a shorthand of mount Sprockets => "/sprockets".
This is different from the match syntax in that it cannot be used for controller/action and it does not assume an anchor at the end of the match. For instance, in the above example, if the client asked for "/sprockets/foo.js", the Sprockets app would have a SCRIPT_NAME of "/sprockets" and PATH_INFO of "/foo.js".
This commit is contained in:
@@ -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!
|
||||
|
||||
|
||||
@@ -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)|
|
||||
|
||||
@@ -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
|
||||
|
||||
36
actionpack/test/dispatch/mount_test.rb
Normal file
36
actionpack/test/dispatch/mount_test.rb
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user