actionpack 4.2.11.1 → 5.2.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +328 -458
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -7
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +45 -49
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +78 -15
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +47 -31
- data/lib/abstract_controller/collector.rb +8 -11
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +25 -25
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +4 -2
- data/lib/abstract_controller/rendering.rb +42 -41
- data/lib/abstract_controller/translation.rb +10 -7
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +12 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +149 -0
- data/lib/action_controller/base.rb +27 -19
- data/lib/action_controller/caching.rb +14 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +10 -15
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +118 -44
- data/lib/action_controller/metal/content_security_policy.rb +52 -0
- data/lib/action_controller/metal/cookies.rb +3 -3
- data/lib/action_controller/metal/data_streaming.rb +27 -46
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +20 -13
- data/lib/action_controller/metal/exceptions.rb +8 -14
- data/lib/action_controller/metal/flash.rb +4 -3
- data/lib/action_controller/metal/force_ssl.rb +23 -21
- data/lib/action_controller/metal/head.rb +21 -19
- data/lib/action_controller/metal/helpers.rb +24 -14
- data/lib/action_controller/metal/http_authentication.rb +65 -58
- data/lib/action_controller/metal/implicit_render.rb +62 -8
- data/lib/action_controller/metal/instrumentation.rb +19 -21
- data/lib/action_controller/metal/live.rb +90 -106
- data/lib/action_controller/metal/mime_responds.rb +33 -46
- data/lib/action_controller/metal/parameter_encoding.rb +51 -0
- data/lib/action_controller/metal/params_wrapper.rb +61 -53
- data/lib/action_controller/metal/redirecting.rb +49 -28
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +72 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +284 -97
- data/lib/action_controller/metal/rescue.rb +9 -16
- data/lib/action_controller/metal/streaming.rb +12 -10
- data/lib/action_controller/metal/strong_parameters.rb +583 -164
- data/lib/action_controller/metal/testing.rb +2 -17
- data/lib/action_controller/metal/url_for.rb +19 -10
- data/lib/action_controller/metal.rb +98 -83
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +117 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +282 -413
- data/lib/action_controller.rb +29 -21
- data/lib/action_dispatch/http/cache.rb +93 -47
- data/lib/action_dispatch/http/content_security_policy.rb +272 -0
- data/lib/action_dispatch/http/filter_parameters.rb +26 -20
- data/lib/action_dispatch/http/filter_redirect.rb +10 -11
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +56 -41
- data/lib/action_dispatch/http/mime_type.rb +134 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameter_filter.rb +25 -11
- data/lib/action_dispatch/http/parameters.rb +98 -39
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +200 -118
- data/lib/action_dispatch/http/response.rb +225 -110
- data/lib/action_dispatch/http/upload.rb +12 -6
- data/lib/action_dispatch/http/url.rb +110 -28
- data/lib/action_dispatch/journey/formatter.rb +55 -32
- data/lib/action_dispatch/journey/gtg/builder.rb +7 -5
- data/lib/action_dispatch/journey/gtg/simulator.rb +3 -9
- data/lib/action_dispatch/journey/gtg/transition_table.rb +17 -16
- data/lib/action_dispatch/journey/nfa/builder.rb +5 -3
- data/lib/action_dispatch/journey/nfa/dot.rb +13 -13
- data/lib/action_dispatch/journey/nfa/simulator.rb +3 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -48
- data/lib/action_dispatch/journey/nodes/node.rb +18 -6
- data/lib/action_dispatch/journey/parser.rb +23 -22
- data/lib/action_dispatch/journey/parser.y +3 -2
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +50 -44
- data/lib/action_dispatch/journey/route.rb +106 -28
- data/lib/action_dispatch/journey/router/utils.rb +20 -11
- data/lib/action_dispatch/journey/router.rb +35 -23
- data/lib/action_dispatch/journey/routes.rb +18 -16
- data/lib/action_dispatch/journey/scanner.rb +18 -15
- data/lib/action_dispatch/journey/visitors.rb +99 -52
- data/lib/action_dispatch/journey.rb +7 -5
- data/lib/action_dispatch/middleware/callbacks.rb +1 -2
- data/lib/action_dispatch/middleware/cookies.rb +304 -193
- data/lib/action_dispatch/middleware/debug_exceptions.rb +152 -57
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +68 -69
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/public_exceptions.rb +27 -25
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +41 -31
- data/lib/action_dispatch/middleware/request_id.rb +17 -9
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -25
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +72 -67
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +26 -22
- data/lib/action_dispatch/middleware/ssl.rb +114 -36
- data/lib/action_dispatch/middleware/stack.rb +31 -44
- data/lib/action_dispatch/middleware/static.rb +57 -50
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +64 -64
- data/lib/action_dispatch/railtie.rb +19 -11
- data/lib/action_dispatch/request/session.rb +106 -59
- data/lib/action_dispatch/request/utils.rb +67 -24
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +58 -67
- data/lib/action_dispatch/routing/mapper.rb +733 -447
- data/lib/action_dispatch/routing/polymorphic_routes.rb +166 -140
- data/lib/action_dispatch/routing/redirection.rb +36 -26
- data/lib/action_dispatch/routing/route_set.rb +321 -291
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +65 -25
- data/lib/action_dispatch/routing.rb +17 -18
- data/lib/action_dispatch/system_test_case.rb +147 -0
- data/lib/action_dispatch/system_testing/browser.rb +49 -0
- data/lib/action_dispatch/system_testing/driver.rb +59 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
- data/lib/action_dispatch/testing/assertion_response.rb +47 -0
- data/lib/action_dispatch/testing/assertions/response.rb +45 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +30 -26
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +348 -209
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +28 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +35 -7
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +56 -38
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,14 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_dispatch/journey"
|
4
|
+
require "active_support/core_ext/object/to_query"
|
5
|
+
require "active_support/core_ext/hash/slice"
|
6
|
+
require "active_support/core_ext/module/redefine_method"
|
7
|
+
require "active_support/core_ext/module/remove_method"
|
8
|
+
require "active_support/core_ext/array/extract_options"
|
9
|
+
require "action_controller/metal/exceptions"
|
10
|
+
require "action_dispatch/http/request"
|
11
|
+
require "action_dispatch/routing/endpoint"
|
12
12
|
|
13
13
|
module ActionDispatch
|
14
14
|
module Routing
|
@@ -20,67 +20,48 @@ module ActionDispatch
|
|
20
20
|
# alias inspect to to_s.
|
21
21
|
alias inspect to_s
|
22
22
|
|
23
|
-
mattr_accessor :relative_url_root
|
24
|
-
|
25
23
|
class Dispatcher < Routing::Endpoint
|
26
|
-
def initialize(
|
27
|
-
@
|
24
|
+
def initialize(raise_on_name_error)
|
25
|
+
@raise_on_name_error = raise_on_name_error
|
28
26
|
end
|
29
27
|
|
30
28
|
def dispatcher?; true; end
|
31
29
|
|
32
30
|
def serve(req)
|
33
|
-
req.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
31
|
+
params = req.path_parameters
|
32
|
+
controller = controller req
|
33
|
+
res = controller.make_response! req
|
34
|
+
dispatch(controller, params[:action], req, res)
|
35
|
+
rescue ActionController::RoutingError
|
36
|
+
if @raise_on_name_error
|
37
|
+
raise
|
38
|
+
else
|
39
|
+
return [404, { "X-Cascade" => "pass" }, []]
|
41
40
|
end
|
42
|
-
|
43
|
-
dispatch(controller, params[:action], req.env)
|
44
41
|
end
|
45
42
|
|
46
|
-
|
47
|
-
normalize_controller!(params)
|
48
|
-
merge_default_action!(params)
|
49
|
-
end
|
43
|
+
private
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
# a user error. However, if the controller was retrieved through a dynamic
|
54
|
-
# segment, as in :controller(/:action), we should simply return nil and
|
55
|
-
# delegate the control back to Rack cascade. Besides, if this is not a default
|
56
|
-
# controller, it means we should respect the @scope[:module] parameter.
|
57
|
-
def controller(params, default_controller=true)
|
58
|
-
if params && params.key?(:controller)
|
59
|
-
controller_param = params[:controller]
|
60
|
-
controller_reference(controller_param)
|
61
|
-
end
|
45
|
+
def controller(req)
|
46
|
+
req.controller_class
|
62
47
|
rescue NameError => e
|
63
|
-
raise ActionController::RoutingError, e.message, e.backtrace
|
48
|
+
raise ActionController::RoutingError, e.message, e.backtrace
|
64
49
|
end
|
65
50
|
|
66
|
-
|
67
|
-
|
68
|
-
def controller_reference(controller_param)
|
69
|
-
const_name = "#{controller_param.camelize}Controller"
|
70
|
-
ActiveSupport::Dependencies.constantize(const_name)
|
51
|
+
def dispatch(controller, action, req, res)
|
52
|
+
controller.dispatch(action, req, res)
|
71
53
|
end
|
54
|
+
end
|
72
55
|
|
73
|
-
|
74
|
-
|
56
|
+
class StaticDispatcher < Dispatcher
|
57
|
+
def initialize(controller_class)
|
58
|
+
super(false)
|
59
|
+
@controller_class = controller_class
|
75
60
|
end
|
76
61
|
|
77
|
-
|
78
|
-
params[:controller] = params[:controller].underscore if params.key?(:controller)
|
79
|
-
end
|
62
|
+
private
|
80
63
|
|
81
|
-
|
82
|
-
params[:action] ||= 'index'
|
83
|
-
end
|
64
|
+
def controller(_); @controller_class; end
|
84
65
|
end
|
85
66
|
|
86
67
|
# A NamedRouteCollection instance is a collection of named routes, and also
|
@@ -88,10 +69,11 @@ module ActionDispatch
|
|
88
69
|
# named routes.
|
89
70
|
class NamedRouteCollection
|
90
71
|
include Enumerable
|
91
|
-
attr_reader :routes, :url_helpers_module
|
72
|
+
attr_reader :routes, :url_helpers_module, :path_helpers_module
|
73
|
+
private :routes
|
92
74
|
|
93
75
|
def initialize
|
94
|
-
@routes
|
76
|
+
@routes = {}
|
95
77
|
@path_helpers = Set.new
|
96
78
|
@url_helpers = Set.new
|
97
79
|
@url_helpers_module = Module.new
|
@@ -103,25 +85,17 @@ module ActionDispatch
|
|
103
85
|
@path_helpers.include?(key) || @url_helpers.include?(key)
|
104
86
|
end
|
105
87
|
|
106
|
-
def helpers
|
107
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
108
|
-
`named_routes.helpers` is deprecated, please use `route_defined?(route_name)`
|
109
|
-
to see if a named route was defined.
|
110
|
-
MSG
|
111
|
-
@path_helpers + @url_helpers
|
112
|
-
end
|
113
|
-
|
114
88
|
def helper_names
|
115
89
|
@path_helpers.map(&:to_s) + @url_helpers.map(&:to_s)
|
116
90
|
end
|
117
91
|
|
118
92
|
def clear!
|
119
93
|
@path_helpers.each do |helper|
|
120
|
-
@path_helpers_module.send :
|
94
|
+
@path_helpers_module.send :remove_method, helper
|
121
95
|
end
|
122
96
|
|
123
97
|
@url_helpers.each do |helper|
|
124
|
-
@url_helpers_module.send :
|
98
|
+
@url_helpers_module.send :remove_method, helper
|
125
99
|
end
|
126
100
|
|
127
101
|
@routes.clear
|
@@ -139,7 +113,7 @@ module ActionDispatch
|
|
139
113
|
@url_helpers_module.send :undef_method, url_name
|
140
114
|
end
|
141
115
|
routes[key] = route
|
142
|
-
define_url_helper @path_helpers_module, route, path_name, route.defaults, name,
|
116
|
+
define_url_helper @path_helpers_module, route, path_name, route.defaults, name, PATH
|
143
117
|
define_url_helper @url_helpers_module, route, url_name, route.defaults, name, UNKNOWN
|
144
118
|
|
145
119
|
@path_helpers << path_name
|
@@ -151,6 +125,7 @@ module ActionDispatch
|
|
151
125
|
end
|
152
126
|
|
153
127
|
def key?(name)
|
128
|
+
return unless name
|
154
129
|
routes.key? name.to_sym
|
155
130
|
end
|
156
131
|
|
@@ -171,23 +146,29 @@ module ActionDispatch
|
|
171
146
|
routes.length
|
172
147
|
end
|
173
148
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
149
|
+
# Given a +name+, defines name_path and name_url helpers.
|
150
|
+
# Used by 'direct', 'resolve', and 'polymorphic' route helpers.
|
151
|
+
def add_url_helper(name, defaults, &block)
|
152
|
+
helper = CustomUrlHelper.new(name, defaults, &block)
|
153
|
+
path_name = :"#{name}_path"
|
154
|
+
url_name = :"#{name}_url"
|
180
155
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
156
|
+
@path_helpers_module.module_eval do
|
157
|
+
define_method(path_name) do |*args|
|
158
|
+
helper.call(self, args, true)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
@url_helpers_module.module_eval do
|
163
|
+
define_method(url_name) do |*args|
|
164
|
+
helper.call(self, args, false)
|
187
165
|
end
|
188
|
-
else
|
189
|
-
@path_helpers_module
|
190
166
|
end
|
167
|
+
|
168
|
+
@path_helpers << path_name
|
169
|
+
@url_helpers << url_name
|
170
|
+
|
171
|
+
self
|
191
172
|
end
|
192
173
|
|
193
174
|
class UrlHelper
|
@@ -218,6 +199,16 @@ module ActionDispatch
|
|
218
199
|
if args.size == arg_size && !inner_options && optimize_routes_generation?(t)
|
219
200
|
options = t.url_options.merge @options
|
220
201
|
options[:path] = optimized_helper(args)
|
202
|
+
|
203
|
+
original_script_name = options.delete(:original_script_name)
|
204
|
+
script_name = t._routes.find_script_name(options)
|
205
|
+
|
206
|
+
if original_script_name
|
207
|
+
script_name = original_script_name + script_name
|
208
|
+
end
|
209
|
+
|
210
|
+
options[:script_name] = script_name
|
211
|
+
|
221
212
|
url_strategy.call options
|
222
213
|
else
|
223
214
|
super
|
@@ -226,38 +217,40 @@ module ActionDispatch
|
|
226
217
|
|
227
218
|
private
|
228
219
|
|
229
|
-
|
230
|
-
|
231
|
-
|
220
|
+
def optimized_helper(args)
|
221
|
+
params = parameterize_args(args) do
|
222
|
+
raise_generation_error(args)
|
223
|
+
end
|
232
224
|
|
233
|
-
|
234
|
-
raise_generation_error(params, missing_keys)
|
225
|
+
@route.format params
|
235
226
|
end
|
236
227
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
def optimize_routes_generation?(t)
|
241
|
-
t.send(:optimize_routes_generation?)
|
242
|
-
end
|
243
|
-
|
244
|
-
def parameterize_args(args)
|
245
|
-
params = {}
|
246
|
-
@required_parts.zip(args.map(&:to_param)) { |k,v| params[k] = v }
|
247
|
-
params
|
248
|
-
end
|
228
|
+
def optimize_routes_generation?(t)
|
229
|
+
t.send(:optimize_routes_generation?)
|
230
|
+
end
|
249
231
|
|
250
|
-
|
251
|
-
|
252
|
-
|
232
|
+
def parameterize_args(args)
|
233
|
+
params = {}
|
234
|
+
@arg_size.times { |i|
|
235
|
+
key = @required_parts[i]
|
236
|
+
value = args[i].to_param
|
237
|
+
yield key if value.nil? || value.empty?
|
238
|
+
params[key] = value
|
239
|
+
}
|
240
|
+
params
|
241
|
+
end
|
253
242
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
243
|
+
def raise_generation_error(args)
|
244
|
+
missing_keys = []
|
245
|
+
params = parameterize_args(args) { |missing_key|
|
246
|
+
missing_keys << missing_key
|
247
|
+
}
|
248
|
+
constraints = Hash[@route.requirements.merge(params).sort_by { |k, v| k.to_s }]
|
249
|
+
message = "No route matches #{constraints.inspect}".dup
|
250
|
+
message << ", missing required keys: #{missing_keys.sort.inspect}"
|
258
251
|
|
259
|
-
|
260
|
-
|
252
|
+
raise ActionController::UrlGenerationError, message
|
253
|
+
end
|
261
254
|
end
|
262
255
|
|
263
256
|
def initialize(route, options, route_name, url_strategy)
|
@@ -272,7 +265,7 @@ module ActionDispatch
|
|
272
265
|
controller_options = t.url_options
|
273
266
|
options = controller_options.merge @options
|
274
267
|
hash = handle_positional_args(controller_options,
|
275
|
-
|
268
|
+
inner_options || {},
|
276
269
|
args,
|
277
270
|
options,
|
278
271
|
@segment_keys)
|
@@ -292,119 +285,130 @@ module ActionDispatch
|
|
292
285
|
if args.size < path_params_size
|
293
286
|
path_params -= controller_options.keys
|
294
287
|
path_params -= result.keys
|
288
|
+
else
|
289
|
+
path_params = path_params.dup
|
290
|
+
end
|
291
|
+
inner_options.each_key do |key|
|
292
|
+
path_params.delete(key)
|
295
293
|
end
|
296
|
-
path_params.each { |param|
|
297
|
-
value = inner_options.fetch(param) { args.shift }
|
298
294
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
295
|
+
args.each_with_index do |arg, index|
|
296
|
+
param = path_params[index]
|
297
|
+
result[param] = arg if param
|
298
|
+
end
|
303
299
|
end
|
304
300
|
|
305
301
|
result.merge!(inner_options)
|
306
302
|
end
|
307
|
-
|
308
|
-
DEPRECATED_STRING_OPTIONS = %w[controller action]
|
309
|
-
|
310
|
-
def deprecate_string_options(options)
|
311
|
-
options ||= {}
|
312
|
-
deprecated_string_options = options.keys & DEPRECATED_STRING_OPTIONS
|
313
|
-
if deprecated_string_options.any?
|
314
|
-
msg = "Calling URL helpers with string keys #{deprecated_string_options.join(", ")} is deprecated. Use symbols instead."
|
315
|
-
ActiveSupport::Deprecation.warn(msg)
|
316
|
-
deprecated_string_options.each do |option|
|
317
|
-
value = options.delete(option)
|
318
|
-
options[option.to_sym] = value
|
319
|
-
end
|
320
|
-
end
|
321
|
-
options
|
322
|
-
end
|
323
303
|
end
|
324
304
|
|
325
305
|
private
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
306
|
+
# Create a URL helper allowing ordered parameters to be associated
|
307
|
+
# with corresponding dynamic segments, so you can do:
|
308
|
+
#
|
309
|
+
# foo_url(bar, baz, bang)
|
310
|
+
#
|
311
|
+
# Instead of:
|
312
|
+
#
|
313
|
+
# foo_url(bar: bar, baz: baz, bang: bang)
|
314
|
+
#
|
315
|
+
# Also allow options hash, so you can do:
|
316
|
+
#
|
317
|
+
# foo_url(bar, baz, bang, sort_by: 'baz')
|
318
|
+
#
|
319
|
+
def define_url_helper(mod, route, name, opts, route_key, url_strategy)
|
320
|
+
helper = UrlHelper.create(route, opts, route_key, url_strategy)
|
321
|
+
mod.module_eval do
|
322
|
+
define_method(name) do |*args|
|
323
|
+
last = args.last
|
324
|
+
options = \
|
325
|
+
case last
|
326
|
+
when Hash
|
327
|
+
args.pop
|
328
|
+
when ActionController::Parameters
|
329
|
+
args.pop.to_h
|
330
|
+
end
|
331
|
+
helper.call self, args, options
|
332
|
+
end
|
346
333
|
end
|
347
334
|
end
|
348
|
-
end
|
349
335
|
end
|
350
336
|
|
351
337
|
# strategy for building urls to send to the client
|
352
338
|
PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
|
353
|
-
FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
|
354
339
|
UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) }
|
355
|
-
LEGACY = ->(options) {
|
356
|
-
if options.key?(:only_path)
|
357
|
-
if options[:only_path]
|
358
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
359
|
-
You are calling a `*_path` helper with the `only_path` option
|
360
|
-
explicitly set to `true`. This option will stop working on
|
361
|
-
path helpers in Rails 5. Simply remove the `only_path: true`
|
362
|
-
argument from your call as it is redundant when applied to a
|
363
|
-
path helper.
|
364
|
-
MSG
|
365
|
-
|
366
|
-
PATH.call(options)
|
367
|
-
else
|
368
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
369
|
-
You are calling a `*_path` helper with the `only_path` option
|
370
|
-
explicitly set to `false`. This option will stop working on
|
371
|
-
path helpers in Rails 5. Use the corresponding `*_url` helper
|
372
|
-
instead.
|
373
|
-
MSG
|
374
|
-
|
375
|
-
FULL.call(options)
|
376
|
-
end
|
377
|
-
else
|
378
|
-
PATH.call(options)
|
379
|
-
end
|
380
|
-
}
|
381
340
|
|
382
341
|
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
|
383
342
|
attr_accessor :disable_clear_and_finalize, :resources_path_names
|
384
|
-
attr_accessor :default_url_options
|
343
|
+
attr_accessor :default_url_options
|
344
|
+
attr_reader :env_key, :polymorphic_mappings
|
385
345
|
|
386
346
|
alias :routes :set
|
387
347
|
|
388
348
|
def self.default_resources_path_names
|
389
|
-
{ :
|
349
|
+
{ new: "new", edit: "edit" }
|
390
350
|
end
|
391
351
|
|
392
|
-
def
|
352
|
+
def self.new_with_config(config)
|
353
|
+
route_set_config = DEFAULT_CONFIG
|
354
|
+
|
355
|
+
# engines apparently don't have this set
|
356
|
+
if config.respond_to? :relative_url_root
|
357
|
+
route_set_config.relative_url_root = config.relative_url_root
|
358
|
+
end
|
359
|
+
|
360
|
+
if config.respond_to? :api_only
|
361
|
+
route_set_config.api_only = config.api_only
|
362
|
+
end
|
363
|
+
|
364
|
+
new route_set_config
|
365
|
+
end
|
366
|
+
|
367
|
+
Config = Struct.new :relative_url_root, :api_only
|
368
|
+
|
369
|
+
DEFAULT_CONFIG = Config.new(nil, false)
|
370
|
+
|
371
|
+
def initialize(config = DEFAULT_CONFIG)
|
393
372
|
self.named_routes = NamedRouteCollection.new
|
394
373
|
self.resources_path_names = self.class.default_resources_path_names
|
395
374
|
self.default_url_options = {}
|
396
|
-
self.request_class = request_class
|
397
375
|
|
376
|
+
@config = config
|
398
377
|
@append = []
|
399
378
|
@prepend = []
|
400
379
|
@disable_clear_and_finalize = false
|
401
380
|
@finalized = false
|
381
|
+
@env_key = "ROUTES_#{object_id}_SCRIPT_NAME".freeze
|
402
382
|
|
403
383
|
@set = Journey::Routes.new
|
404
384
|
@router = Journey::Router.new @set
|
405
|
-
@formatter = Journey::Formatter.new
|
385
|
+
@formatter = Journey::Formatter.new self
|
386
|
+
@polymorphic_mappings = {}
|
387
|
+
end
|
388
|
+
|
389
|
+
def eager_load!
|
390
|
+
router.eager_load!
|
391
|
+
routes.each(&:eager_load!)
|
392
|
+
nil
|
393
|
+
end
|
394
|
+
|
395
|
+
def relative_url_root
|
396
|
+
@config.relative_url_root
|
397
|
+
end
|
398
|
+
|
399
|
+
def api_only?
|
400
|
+
@config.api_only
|
401
|
+
end
|
402
|
+
|
403
|
+
def request_class
|
404
|
+
ActionDispatch::Request
|
406
405
|
end
|
407
406
|
|
407
|
+
def make_request(env)
|
408
|
+
request_class.new env
|
409
|
+
end
|
410
|
+
private :make_request
|
411
|
+
|
408
412
|
def draw(&block)
|
409
413
|
clear! unless @disable_clear_and_finalize
|
410
414
|
eval_block(block)
|
@@ -421,10 +425,6 @@ module ActionDispatch
|
|
421
425
|
end
|
422
426
|
|
423
427
|
def eval_block(block)
|
424
|
-
if block.arity == 1
|
425
|
-
raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
|
426
|
-
"Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
|
427
|
-
end
|
428
428
|
mapper = Mapper.new(self)
|
429
429
|
if default_scope
|
430
430
|
mapper.with_default_scope(default_scope, &block)
|
@@ -445,13 +445,10 @@ module ActionDispatch
|
|
445
445
|
named_routes.clear
|
446
446
|
set.clear
|
447
447
|
formatter.clear
|
448
|
+
@polymorphic_mappings.clear
|
448
449
|
@prepend.each { |blk| eval_block(blk) }
|
449
450
|
end
|
450
451
|
|
451
|
-
def dispatcher(defaults)
|
452
|
-
Routing::RouteSet::Dispatcher.new(defaults)
|
453
|
-
end
|
454
|
-
|
455
452
|
module MountedHelpers
|
456
453
|
extend ActiveSupport::Concern
|
457
454
|
include UrlFor
|
@@ -465,7 +462,7 @@ module ActionDispatch
|
|
465
462
|
MountedHelpers
|
466
463
|
end
|
467
464
|
|
468
|
-
def define_mounted_helper(name)
|
465
|
+
def define_mounted_helper(name, script_namer = nil)
|
469
466
|
return if MountedHelpers.method_defined?(name)
|
470
467
|
|
471
468
|
routes = self
|
@@ -473,7 +470,7 @@ module ActionDispatch
|
|
473
470
|
|
474
471
|
MountedHelpers.class_eval do
|
475
472
|
define_method "_#{name}" do
|
476
|
-
RoutesProxy.new(routes, _routes_context, helpers)
|
473
|
+
RoutesProxy.new(routes, _routes_context, helpers, script_namer)
|
477
474
|
end
|
478
475
|
end
|
479
476
|
|
@@ -493,10 +490,50 @@ module ActionDispatch
|
|
493
490
|
|
494
491
|
# Define url_for in the singleton level so one can do:
|
495
492
|
# Rails.application.routes.url_helpers.url_for(args)
|
496
|
-
|
497
|
-
|
498
|
-
|
493
|
+
proxy_class = Class.new do
|
494
|
+
include UrlFor
|
495
|
+
include routes.named_routes.path_helpers_module
|
496
|
+
include routes.named_routes.url_helpers_module
|
497
|
+
|
499
498
|
attr_reader :_routes
|
499
|
+
|
500
|
+
def initialize(routes)
|
501
|
+
@_routes = routes
|
502
|
+
end
|
503
|
+
|
504
|
+
def optimize_routes_generation?
|
505
|
+
@_routes.optimize_routes_generation?
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
@_proxy = proxy_class.new(routes)
|
510
|
+
|
511
|
+
class << self
|
512
|
+
def url_for(options)
|
513
|
+
@_proxy.url_for(options)
|
514
|
+
end
|
515
|
+
|
516
|
+
def full_url_for(options)
|
517
|
+
@_proxy.full_url_for(options)
|
518
|
+
end
|
519
|
+
|
520
|
+
def route_for(name, *args)
|
521
|
+
@_proxy.route_for(name, *args)
|
522
|
+
end
|
523
|
+
|
524
|
+
def optimize_routes_generation?
|
525
|
+
@_proxy.optimize_routes_generation?
|
526
|
+
end
|
527
|
+
|
528
|
+
def polymorphic_url(record_or_hash_or_array, options = {})
|
529
|
+
@_proxy.polymorphic_url(record_or_hash_or_array, options)
|
530
|
+
end
|
531
|
+
|
532
|
+
def polymorphic_path(record_or_hash_or_array, options = {})
|
533
|
+
@_proxy.polymorphic_path(record_or_hash_or_array, options)
|
534
|
+
end
|
535
|
+
|
536
|
+
def _routes; @_proxy._routes; end
|
500
537
|
def url_options; {}; end
|
501
538
|
end
|
502
539
|
|
@@ -513,16 +550,14 @@ module ActionDispatch
|
|
513
550
|
|
514
551
|
if supports_path
|
515
552
|
path_helpers = routes.named_routes.path_helpers_module
|
516
|
-
else
|
517
|
-
path_helpers = routes.named_routes.path_helpers_module(true)
|
518
|
-
end
|
519
553
|
|
520
|
-
|
521
|
-
|
554
|
+
include path_helpers
|
555
|
+
extend path_helpers
|
556
|
+
end
|
522
557
|
|
523
558
|
# plus a singleton class method called _routes ...
|
524
559
|
included do
|
525
|
-
|
560
|
+
redefine_singleton_method(:_routes) { routes }
|
526
561
|
end
|
527
562
|
|
528
563
|
# And an instance method _routes. Note that
|
@@ -542,7 +577,7 @@ module ActionDispatch
|
|
542
577
|
routes.empty?
|
543
578
|
end
|
544
579
|
|
545
|
-
def add_route(
|
580
|
+
def add_route(mapping, name)
|
546
581
|
raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
|
547
582
|
|
548
583
|
if name && named_routes[name]
|
@@ -553,74 +588,70 @@ module ActionDispatch
|
|
553
588
|
"http://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
|
554
589
|
end
|
555
590
|
|
556
|
-
|
557
|
-
ast = conditions.delete :parsed_path_info
|
558
|
-
path = build_path(path, ast, requirements, anchor)
|
559
|
-
conditions = build_conditions(conditions, path.names.map { |x| x.to_sym })
|
560
|
-
|
561
|
-
route = @set.add_route(app, path, conditions, defaults, name)
|
591
|
+
route = @set.add_route(name, mapping)
|
562
592
|
named_routes[name] = route if name
|
563
|
-
route
|
564
|
-
end
|
565
593
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
anchor)
|
573
|
-
|
574
|
-
pattern = Journey::Path::Pattern.new(strexp)
|
575
|
-
|
576
|
-
builder = Journey::GTG::Builder.new pattern.spec
|
594
|
+
if route.segment_keys.include?(:controller)
|
595
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
596
|
+
Using a dynamic :controller segment in a route is deprecated and
|
597
|
+
will be removed in Rails 6.0.
|
598
|
+
MSG
|
599
|
+
end
|
577
600
|
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
601
|
+
if route.segment_keys.include?(:action)
|
602
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
603
|
+
Using a dynamic :action segment in a route is deprecated and
|
604
|
+
will be removed in Rails 6.0.
|
605
|
+
MSG
|
606
|
+
end
|
583
607
|
|
584
|
-
|
585
|
-
|
586
|
-
builder.followpos(n).first
|
587
|
-
}.find_all(&:symbol?)
|
608
|
+
route
|
609
|
+
end
|
588
610
|
|
589
|
-
|
590
|
-
|
591
|
-
|
611
|
+
def add_polymorphic_mapping(klass, options, &block)
|
612
|
+
@polymorphic_mappings[klass] = CustomUrlHelper.new(klass, options, &block)
|
613
|
+
end
|
592
614
|
|
593
|
-
|
615
|
+
def add_url_helper(name, options, &block)
|
616
|
+
named_routes.add_url_helper(name, options, &block)
|
594
617
|
end
|
595
|
-
private :build_path
|
596
618
|
|
597
|
-
|
598
|
-
|
619
|
+
class CustomUrlHelper
|
620
|
+
attr_reader :name, :defaults, :block
|
599
621
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
verbs = conditions[:request_method] || []
|
605
|
-
unless verbs.empty?
|
606
|
-
conditions[:request_method] = %r[^#{verbs.join('|')}$]
|
622
|
+
def initialize(name, defaults, &block)
|
623
|
+
@name = name
|
624
|
+
@defaults = defaults
|
625
|
+
@block = block
|
607
626
|
end
|
608
627
|
|
609
|
-
|
610
|
-
|
611
|
-
|
628
|
+
def call(t, args, only_path = false)
|
629
|
+
options = args.extract_options!
|
630
|
+
url = t.full_url_for(eval_block(t, args, options))
|
631
|
+
|
632
|
+
if only_path
|
633
|
+
"/" + url.partition(%r{(?<!/)/(?!/)}).last
|
634
|
+
else
|
635
|
+
url
|
636
|
+
end
|
612
637
|
end
|
638
|
+
|
639
|
+
private
|
640
|
+
def eval_block(t, args, options)
|
641
|
+
t.instance_exec(*args, merge_defaults(options), &block)
|
642
|
+
end
|
643
|
+
|
644
|
+
def merge_defaults(options)
|
645
|
+
defaults ? defaults.merge(options) : options
|
646
|
+
end
|
613
647
|
end
|
614
|
-
private :build_conditions
|
615
648
|
|
616
649
|
class Generator
|
617
650
|
PARAMETERIZE = lambda do |name, value|
|
618
651
|
if name == :controller
|
619
652
|
value
|
620
|
-
|
621
|
-
value.
|
622
|
-
elsif param = value.to_param
|
623
|
-
param
|
653
|
+
else
|
654
|
+
value.to_param
|
624
655
|
end
|
625
656
|
end
|
626
657
|
|
@@ -628,16 +659,14 @@ module ActionDispatch
|
|
628
659
|
|
629
660
|
def initialize(named_route, options, recall, set)
|
630
661
|
@named_route = named_route
|
631
|
-
@options = options
|
632
|
-
@recall = recall
|
662
|
+
@options = options
|
663
|
+
@recall = recall
|
633
664
|
@set = set
|
634
665
|
|
635
|
-
normalize_recall!
|
636
666
|
normalize_options!
|
637
667
|
normalize_controller_action_id!
|
638
668
|
use_relative_controller!
|
639
669
|
normalize_controller!
|
640
|
-
normalize_action!
|
641
670
|
end
|
642
671
|
|
643
672
|
def controller
|
@@ -651,16 +680,11 @@ module ActionDispatch
|
|
651
680
|
def use_recall_for(key)
|
652
681
|
if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
|
653
682
|
if !named_route_exists? || segment_keys.include?(key)
|
654
|
-
@options[key] = @recall
|
683
|
+
@options[key] = @recall[key]
|
655
684
|
end
|
656
685
|
end
|
657
686
|
end
|
658
687
|
|
659
|
-
# Set 'index' as default action for recall
|
660
|
-
def normalize_recall!
|
661
|
-
@recall[:action] ||= 'index'
|
662
|
-
end
|
663
|
-
|
664
688
|
def normalize_options!
|
665
689
|
# If an explicit :controller was given, always make :action explicit
|
666
690
|
# too, so that action expiry works as expected for things like
|
@@ -672,12 +696,12 @@ module ActionDispatch
|
|
672
696
|
# be "index", not the recalled action of "show".
|
673
697
|
|
674
698
|
if options[:controller]
|
675
|
-
options[:action] ||=
|
699
|
+
options[:action] ||= "index"
|
676
700
|
options[:controller] = options[:controller].to_s
|
677
701
|
end
|
678
702
|
|
679
703
|
if options.key?(:action)
|
680
|
-
options[:action] = (options[:action] ||
|
704
|
+
options[:action] = (options[:action] || "index").to_s
|
681
705
|
end
|
682
706
|
end
|
683
707
|
|
@@ -687,8 +711,8 @@ module ActionDispatch
|
|
687
711
|
# :controller, :action or :id is not found, don't pull any
|
688
712
|
# more keys from the recall.
|
689
713
|
def normalize_controller_action_id!
|
690
|
-
use_recall_for(:controller)
|
691
|
-
use_recall_for(:action)
|
714
|
+
use_recall_for(:controller) || return
|
715
|
+
use_recall_for(:action) || return
|
692
716
|
use_recall_for(:id)
|
693
717
|
end
|
694
718
|
|
@@ -696,7 +720,7 @@ module ActionDispatch
|
|
696
720
|
# is specified, the controller becomes "foo/baz/bat"
|
697
721
|
def use_relative_controller!
|
698
722
|
if !named_route && different_controller? && !controller.start_with?("/")
|
699
|
-
old_parts = current_controller.split(
|
723
|
+
old_parts = current_controller.split("/")
|
700
724
|
size = controller.count("/") + 1
|
701
725
|
parts = old_parts[0...-size] << controller
|
702
726
|
@options[:controller] = parts.join("/")
|
@@ -705,13 +729,12 @@ module ActionDispatch
|
|
705
729
|
|
706
730
|
# Remove leading slashes from controllers
|
707
731
|
def normalize_controller!
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
@recall[:action] = @options.delete(:action)
|
732
|
+
if controller
|
733
|
+
if controller.start_with?("/".freeze)
|
734
|
+
@options[:controller] = controller[1..-1]
|
735
|
+
else
|
736
|
+
@options[:controller] = controller
|
737
|
+
end
|
715
738
|
end
|
716
739
|
end
|
717
740
|
|
@@ -738,11 +761,11 @@ module ActionDispatch
|
|
738
761
|
|
739
762
|
# Generate the path indicated by the arguments, and return an array of
|
740
763
|
# the keys that were not used to generate it.
|
741
|
-
def extra_keys(options, recall={})
|
764
|
+
def extra_keys(options, recall = {})
|
742
765
|
generate_extras(options, recall).last
|
743
766
|
end
|
744
767
|
|
745
|
-
def generate_extras(options, recall={})
|
768
|
+
def generate_extras(options, recall = {})
|
746
769
|
route_key = options.delete :use_route
|
747
770
|
path, params = generate(route_key, options, recall)
|
748
771
|
return path, params.keys
|
@@ -762,7 +785,7 @@ module ActionDispatch
|
|
762
785
|
end
|
763
786
|
|
764
787
|
def find_script_name(options)
|
765
|
-
options.delete(:script_name) || find_relative_url_root(options) ||
|
788
|
+
options.delete(:script_name) || find_relative_url_root(options) || ""
|
766
789
|
end
|
767
790
|
|
768
791
|
def find_relative_url_root(options)
|
@@ -784,7 +807,7 @@ module ActionDispatch
|
|
784
807
|
password = options.delete :password
|
785
808
|
end
|
786
809
|
|
787
|
-
recall
|
810
|
+
recall = options.delete(:_recall) { {} }
|
788
811
|
|
789
812
|
original_script_name = options.delete(:original_script_name)
|
790
813
|
script_name = find_script_name options
|
@@ -812,7 +835,7 @@ module ActionDispatch
|
|
812
835
|
end
|
813
836
|
|
814
837
|
def call(env)
|
815
|
-
req =
|
838
|
+
req = make_request(env)
|
816
839
|
req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
|
817
840
|
@router.serve(req)
|
818
841
|
end
|
@@ -823,12 +846,16 @@ module ActionDispatch
|
|
823
846
|
extras = environment[:extras] || {}
|
824
847
|
|
825
848
|
begin
|
826
|
-
env = Rack::MockRequest.env_for(path,
|
849
|
+
env = Rack::MockRequest.env_for(path, method: method)
|
827
850
|
rescue URI::InvalidURIError => e
|
828
851
|
raise ActionController::RoutingError, e.message
|
829
852
|
end
|
830
853
|
|
831
|
-
req =
|
854
|
+
req = make_request(env)
|
855
|
+
recognize_path_with_request(req, path, extras)
|
856
|
+
end
|
857
|
+
|
858
|
+
def recognize_path_with_request(req, path, extras, raise_on_missing: true)
|
832
859
|
@router.recognize(req) do |route, params|
|
833
860
|
params.merge!(extras)
|
834
861
|
params.each do |key, value|
|
@@ -837,22 +864,25 @@ module ActionDispatch
|
|
837
864
|
params[key] = URI.parser.unescape(value)
|
838
865
|
end
|
839
866
|
end
|
840
|
-
|
841
|
-
req.path_parameters = old_params.merge params
|
867
|
+
req.path_parameters = params
|
842
868
|
app = route.app
|
843
869
|
if app.matches?(req) && app.dispatcher?
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
dispatcher.prepare_params!(params)
|
848
|
-
return params
|
849
|
-
else
|
870
|
+
begin
|
871
|
+
req.controller_class
|
872
|
+
rescue NameError
|
850
873
|
raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller"
|
851
874
|
end
|
875
|
+
|
876
|
+
return req.path_parameters
|
877
|
+
elsif app.matches?(req) && app.engine?
|
878
|
+
path_parameters = app.rack_app.routes.recognize_path_with_request(req, path, extras, raise_on_missing: false)
|
879
|
+
return path_parameters if path_parameters
|
852
880
|
end
|
853
881
|
end
|
854
882
|
|
855
|
-
|
883
|
+
if raise_on_missing
|
884
|
+
raise ActionController::RoutingError, "No route matches #{path.inspect}"
|
885
|
+
end
|
856
886
|
end
|
857
887
|
end
|
858
888
|
# :startdoc:
|