actionpack 3.2.19 → 4.2.11.3
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 +7 -0
- data/CHANGELOG.md +412 -503
- data/MIT-LICENSE +1 -1
- data/README.rdoc +11 -294
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +52 -18
- data/lib/abstract_controller/callbacks.rb +87 -89
- data/lib/abstract_controller/collector.rb +17 -3
- data/lib/abstract_controller/helpers.rb +41 -14
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
- data/lib/abstract_controller/rendering.rb +65 -118
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +7 -7
- data/lib/abstract_controller.rb +2 -10
- data/lib/action_controller/base.rb +61 -28
- data/lib/action_controller/caching/fragments.rb +30 -54
- data/lib/action_controller/caching.rb +38 -35
- data/lib/action_controller/log_subscriber.rb +35 -18
- data/lib/action_controller/metal/conditional_get.rb +103 -34
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +41 -9
- data/lib/action_controller/metal/force_ssl.rb +70 -12
- data/lib/action_controller/metal/head.rb +30 -7
- data/lib/action_controller/metal/helpers.rb +11 -11
- data/lib/action_controller/metal/hide_actions.rb +0 -1
- data/lib/action_controller/metal/http_authentication.rb +140 -94
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +11 -7
- data/lib/action_controller/metal/live.rb +328 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -152
- data/lib/action_controller/metal/params_wrapper.rb +126 -81
- data/lib/action_controller/metal/rack_delegation.rb +10 -4
- data/lib/action_controller/metal/redirecting.rb +44 -41
- data/lib/action_controller/metal/renderers.rb +48 -19
- data/lib/action_controller/metal/rendering.rb +46 -11
- data/lib/action_controller/metal/request_forgery_protection.rb +250 -29
- data/lib/action_controller/metal/streaming.rb +30 -38
- data/lib/action_controller/metal/strong_parameters.rb +669 -0
- data/lib/action_controller/metal/testing.rb +12 -18
- data/lib/action_controller/metal/url_for.rb +31 -29
- data/lib/action_controller/metal.rb +31 -40
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +38 -18
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/test_case.rb +359 -173
- data/lib/action_controller.rb +9 -16
- data/lib/action_dispatch/http/cache.rb +64 -11
- data/lib/action_dispatch/http/filter_parameters.rb +20 -10
- data/lib/action_dispatch/http/filter_redirect.rb +38 -0
- data/lib/action_dispatch/http/headers.rb +85 -17
- data/lib/action_dispatch/http/mime_negotiation.rb +55 -5
- data/lib/action_dispatch/http/mime_type.rb +167 -114
- data/lib/action_dispatch/http/mime_types.rb +2 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +30 -46
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +108 -45
- data/lib/action_dispatch/http/response.rb +247 -48
- data/lib/action_dispatch/http/upload.rb +60 -29
- data/lib/action_dispatch/http/url.rb +135 -45
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +166 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +47 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +157 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +128 -0
- data/lib/action_dispatch/journey/parser.rb +198 -0
- data/lib/action_dispatch/journey/parser.y +49 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +193 -0
- data/lib/action_dispatch/journey/route.rb +125 -0
- data/lib/action_dispatch/journey/router/strexp.rb +27 -0
- data/lib/action_dispatch/journey/router/utils.rb +93 -0
- data/lib/action_dispatch/journey/router.rb +144 -0
- data/lib/action_dispatch/journey/routes.rb +80 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +221 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/middleware/callbacks.rb +16 -11
- data/lib/action_dispatch/middleware/cookies.rb +346 -125
- data/lib/action_dispatch/middleware/debug_exceptions.rb +52 -24
- data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -9
- data/lib/action_dispatch/middleware/flash.rb +85 -72
- data/lib/action_dispatch/middleware/params_parser.rb +16 -31
- data/lib/action_dispatch/middleware/public_exceptions.rb +39 -14
- data/lib/action_dispatch/middleware/reloader.rb +16 -7
- data/lib/action_dispatch/middleware/remote_ip.rb +132 -40
- data/lib/action_dispatch/middleware/request_id.rb +3 -7
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +84 -29
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +15 -44
- data/lib/action_dispatch/middleware/ssl.rb +72 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +80 -23
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +34 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +27 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +133 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
- data/lib/action_dispatch/railtie.rb +19 -6
- data/lib/action_dispatch/request/session.rb +193 -0
- data/lib/action_dispatch/request/utils.rb +35 -0
- data/lib/action_dispatch/routing/endpoint.rb +10 -0
- data/lib/action_dispatch/routing/inspector.rb +234 -0
- data/lib/action_dispatch/routing/mapper.rb +897 -436
- data/lib/action_dispatch/routing/polymorphic_routes.rb +213 -92
- data/lib/action_dispatch/routing/redirection.rb +97 -37
- data/lib/action_dispatch/routing/route_set.rb +432 -239
- data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
- data/lib/action_dispatch/routing/url_for.rb +63 -34
- data/lib/action_dispatch/routing.rb +57 -89
- data/lib/action_dispatch/testing/assertions/dom.rb +2 -36
- data/lib/action_dispatch/testing/assertions/response.rb +24 -38
- data/lib/action_dispatch/testing/assertions/routing.rb +55 -54
- data/lib/action_dispatch/testing/assertions/selector.rb +2 -434
- data/lib/action_dispatch/testing/assertions/tag.rb +2 -137
- data/lib/action_dispatch/testing/assertions.rb +11 -7
- data/lib/action_dispatch/testing/integration.rb +88 -72
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +13 -9
- data/lib/action_dispatch/testing/test_response.rb +1 -5
- data/lib/action_dispatch.rb +24 -21
- data/lib/action_pack/gem_version.rb +15 -0
- data/lib/action_pack/version.rb +5 -7
- data/lib/action_pack.rb +1 -1
- metadata +181 -292
- data/lib/abstract_controller/layouts.rb +0 -423
- data/lib/abstract_controller/view_paths.rb +0 -96
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/integration_test.rb +0 -2
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/deprecated.rb +0 -3
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/responder.rb +0 -286
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_controller/record_identifier.rb +0 -85
- data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
- data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
- data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
- data/lib/action_controller/vendor/html-scanner.rb +0 -20
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/base.rb +0 -220
- data/lib/action_view/buffers.rb +0 -43
- data/lib/action_view/context.rb +0 -36
- data/lib/action_view/flows.rb +0 -79
- data/lib/action_view/helpers/active_model_helper.rb +0 -50
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
- data/lib/action_view/helpers/cache_helper.rb +0 -64
- data/lib/action_view/helpers/capture_helper.rb +0 -203
- data/lib/action_view/helpers/controller_helper.rb +0 -25
- data/lib/action_view/helpers/csrf_helper.rb +0 -32
- data/lib/action_view/helpers/date_helper.rb +0 -1062
- data/lib/action_view/helpers/debug_helper.rb +0 -40
- data/lib/action_view/helpers/form_helper.rb +0 -1486
- data/lib/action_view/helpers/form_options_helper.rb +0 -658
- data/lib/action_view/helpers/form_tag_helper.rb +0 -685
- data/lib/action_view/helpers/javascript_helper.rb +0 -110
- data/lib/action_view/helpers/number_helper.rb +0 -622
- data/lib/action_view/helpers/output_safety_helper.rb +0 -38
- data/lib/action_view/helpers/record_tag_helper.rb +0 -111
- data/lib/action_view/helpers/rendering_helper.rb +0 -90
- data/lib/action_view/helpers/sanitize_helper.rb +0 -259
- data/lib/action_view/helpers/tag_helper.rb +0 -160
- data/lib/action_view/helpers/text_helper.rb +0 -426
- data/lib/action_view/helpers/translation_helper.rb +0 -91
- data/lib/action_view/helpers/url_helper.rb +0 -693
- data/lib/action_view/helpers.rb +0 -60
- data/lib/action_view/locale/en.yml +0 -160
- data/lib/action_view/log_subscriber.rb +0 -28
- data/lib/action_view/lookup_context.rb +0 -254
- data/lib/action_view/path_set.rb +0 -89
- data/lib/action_view/railtie.rb +0 -55
- data/lib/action_view/renderer/abstract_renderer.rb +0 -41
- data/lib/action_view/renderer/partial_renderer.rb +0 -415
- data/lib/action_view/renderer/renderer.rb +0 -54
- data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
- data/lib/action_view/renderer/template_renderer.rb +0 -94
- data/lib/action_view/template/error.rb +0 -128
- data/lib/action_view/template/handlers/builder.rb +0 -26
- data/lib/action_view/template/handlers/erb.rb +0 -125
- data/lib/action_view/template/handlers.rb +0 -50
- data/lib/action_view/template/resolver.rb +0 -272
- data/lib/action_view/template/text.rb +0 -30
- data/lib/action_view/template.rb +0 -337
- data/lib/action_view/test_case.rb +0 -245
- data/lib/action_view/testing/resolvers.rb +0 -50
- data/lib/action_view.rb +0 -84
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,31 +1,38 @@
|
|
1
|
-
require 'journey'
|
1
|
+
require 'action_dispatch/journey'
|
2
2
|
require 'forwardable'
|
3
|
-
require 'active_support/
|
3
|
+
require 'active_support/concern'
|
4
4
|
require 'active_support/core_ext/object/to_query'
|
5
5
|
require 'active_support/core_ext/hash/slice'
|
6
6
|
require 'active_support/core_ext/module/remove_method'
|
7
|
+
require 'active_support/core_ext/array/extract_options'
|
8
|
+
require 'active_support/core_ext/string/filters'
|
7
9
|
require 'action_controller/metal/exceptions'
|
10
|
+
require 'action_dispatch/http/request'
|
11
|
+
require 'action_dispatch/routing/endpoint'
|
8
12
|
|
9
13
|
module ActionDispatch
|
10
14
|
module Routing
|
11
|
-
|
15
|
+
# :stopdoc:
|
16
|
+
class RouteSet
|
12
17
|
# Since the router holds references to many parts of the system
|
13
18
|
# like engines, controllers and the application itself, inspecting
|
14
19
|
# the route set can actually be really slow, therefore we default
|
15
20
|
# alias inspect to to_s.
|
16
21
|
alias inspect to_s
|
17
22
|
|
18
|
-
|
23
|
+
mattr_accessor :relative_url_root
|
19
24
|
|
20
|
-
class Dispatcher
|
21
|
-
def initialize(
|
22
|
-
@defaults =
|
23
|
-
@glob_param = options.delete(:glob)
|
24
|
-
@controllers = {}
|
25
|
+
class Dispatcher < Routing::Endpoint
|
26
|
+
def initialize(defaults)
|
27
|
+
@defaults = defaults
|
25
28
|
end
|
26
29
|
|
27
|
-
def
|
28
|
-
|
30
|
+
def dispatcher?; true; end
|
31
|
+
|
32
|
+
def serve(req)
|
33
|
+
req.check_path_parameters!
|
34
|
+
params = req.path_parameters
|
35
|
+
|
29
36
|
prepare_params!(params)
|
30
37
|
|
31
38
|
# Just raise undefined constant errors if a controller was specified as default.
|
@@ -33,13 +40,12 @@ module ActionDispatch
|
|
33
40
|
return [404, {'X-Cascade' => 'pass'}, []]
|
34
41
|
end
|
35
42
|
|
36
|
-
dispatch(controller, params[:action], env)
|
43
|
+
dispatch(controller, params[:action], req.env)
|
37
44
|
end
|
38
45
|
|
39
46
|
def prepare_params!(params)
|
40
47
|
normalize_controller!(params)
|
41
48
|
merge_default_action!(params)
|
42
|
-
split_glob_param!(params) if @glob_param
|
43
49
|
end
|
44
50
|
|
45
51
|
# If this is a default_controller (i.e. a controller specified by the user)
|
@@ -60,13 +66,8 @@ module ActionDispatch
|
|
60
66
|
private
|
61
67
|
|
62
68
|
def controller_reference(controller_param)
|
63
|
-
|
64
|
-
|
65
|
-
unless controller = @controllers[controller_param]
|
66
|
-
controller = @controllers[controller_param] =
|
67
|
-
ActiveSupport::Dependencies.reference(controller_name)
|
68
|
-
end
|
69
|
-
controller.get(controller_name)
|
69
|
+
const_name = "#{controller_param.camelize}Controller"
|
70
|
+
ActiveSupport::Dependencies.constantize(const_name)
|
70
71
|
end
|
71
72
|
|
72
73
|
def dispatch(controller, action, env)
|
@@ -80,48 +81,79 @@ module ActionDispatch
|
|
80
81
|
def merge_default_action!(params)
|
81
82
|
params[:action] ||= 'index'
|
82
83
|
end
|
83
|
-
|
84
|
-
def split_glob_param!(params)
|
85
|
-
params[@glob_param] = params[@glob_param].split('/').map { |v| URI.parser.unescape(v) }
|
86
|
-
end
|
87
84
|
end
|
88
85
|
|
89
86
|
# A NamedRouteCollection instance is a collection of named routes, and also
|
90
87
|
# maintains an anonymous module that can be used to install helpers for the
|
91
88
|
# named routes.
|
92
|
-
class NamedRouteCollection
|
89
|
+
class NamedRouteCollection
|
93
90
|
include Enumerable
|
94
|
-
attr_reader :routes, :
|
91
|
+
attr_reader :routes, :url_helpers_module
|
95
92
|
|
96
93
|
def initialize
|
97
|
-
@routes
|
98
|
-
@
|
94
|
+
@routes = {}
|
95
|
+
@path_helpers = Set.new
|
96
|
+
@url_helpers = Set.new
|
97
|
+
@url_helpers_module = Module.new
|
98
|
+
@path_helpers_module = Module.new
|
99
|
+
end
|
100
|
+
|
101
|
+
def route_defined?(name)
|
102
|
+
key = name.to_sym
|
103
|
+
@path_helpers.include?(key) || @url_helpers.include?(key)
|
104
|
+
end
|
99
105
|
|
100
|
-
|
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
|
101
112
|
end
|
102
113
|
|
103
114
|
def helper_names
|
104
|
-
|
115
|
+
@path_helpers.map(&:to_s) + @url_helpers.map(&:to_s)
|
105
116
|
end
|
106
117
|
|
107
118
|
def clear!
|
108
|
-
@
|
109
|
-
@
|
119
|
+
@path_helpers.each do |helper|
|
120
|
+
@path_helpers_module.send :undef_method, helper
|
121
|
+
end
|
122
|
+
|
123
|
+
@url_helpers.each do |helper|
|
124
|
+
@url_helpers_module.send :undef_method, helper
|
110
125
|
end
|
111
126
|
|
112
127
|
@routes.clear
|
113
|
-
@
|
128
|
+
@path_helpers.clear
|
129
|
+
@url_helpers.clear
|
114
130
|
end
|
115
131
|
|
116
132
|
def add(name, route)
|
117
|
-
|
118
|
-
|
133
|
+
key = name.to_sym
|
134
|
+
path_name = :"#{name}_path"
|
135
|
+
url_name = :"#{name}_url"
|
136
|
+
|
137
|
+
if routes.key? key
|
138
|
+
@path_helpers_module.send :undef_method, path_name
|
139
|
+
@url_helpers_module.send :undef_method, url_name
|
140
|
+
end
|
141
|
+
routes[key] = route
|
142
|
+
define_url_helper @path_helpers_module, route, path_name, route.defaults, name, LEGACY
|
143
|
+
define_url_helper @url_helpers_module, route, url_name, route.defaults, name, UNKNOWN
|
144
|
+
|
145
|
+
@path_helpers << path_name
|
146
|
+
@url_helpers << url_name
|
119
147
|
end
|
120
148
|
|
121
149
|
def get(name)
|
122
150
|
routes[name.to_sym]
|
123
151
|
end
|
124
152
|
|
153
|
+
def key?(name)
|
154
|
+
routes.key? name.to_sym
|
155
|
+
end
|
156
|
+
|
125
157
|
alias []= add
|
126
158
|
alias [] get
|
127
159
|
alias clear clear!
|
@@ -139,90 +171,217 @@ module ActionDispatch
|
|
139
171
|
routes.length
|
140
172
|
end
|
141
173
|
|
142
|
-
def
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
174
|
+
def path_helpers_module(warn = false)
|
175
|
+
if warn
|
176
|
+
mod = @path_helpers_module
|
177
|
+
helpers = @path_helpers
|
178
|
+
Module.new do
|
179
|
+
include mod
|
149
180
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
181
|
+
helpers.each do |meth|
|
182
|
+
define_method(meth) do |*args, &block|
|
183
|
+
ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead")
|
184
|
+
super(*args, &block)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
else
|
189
|
+
@path_helpers_module
|
154
190
|
end
|
155
191
|
end
|
156
192
|
|
157
|
-
|
158
|
-
def
|
159
|
-
|
193
|
+
class UrlHelper
|
194
|
+
def self.create(route, options, route_name, url_strategy)
|
195
|
+
if optimize_helper?(route)
|
196
|
+
OptimizedUrlHelper.new(route, options, route_name, url_strategy)
|
197
|
+
else
|
198
|
+
new route, options, route_name, url_strategy
|
199
|
+
end
|
160
200
|
end
|
161
201
|
|
162
|
-
def
|
163
|
-
|
202
|
+
def self.optimize_helper?(route)
|
203
|
+
!route.glob? && route.path.requirements.empty?
|
164
204
|
end
|
165
205
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
206
|
+
attr_reader :url_strategy, :route_name
|
207
|
+
|
208
|
+
class OptimizedUrlHelper < UrlHelper
|
209
|
+
attr_reader :arg_size
|
210
|
+
|
211
|
+
def initialize(route, options, route_name, url_strategy)
|
212
|
+
super
|
213
|
+
@required_parts = @route.required_parts
|
214
|
+
@arg_size = @required_parts.size
|
215
|
+
end
|
216
|
+
|
217
|
+
def call(t, args, inner_options)
|
218
|
+
if args.size == arg_size && !inner_options && optimize_routes_generation?(t)
|
219
|
+
options = t.url_options.merge @options
|
220
|
+
options[:path] = optimized_helper(args)
|
221
|
+
url_strategy.call options
|
222
|
+
else
|
223
|
+
super
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
private
|
228
|
+
|
229
|
+
def optimized_helper(args)
|
230
|
+
params = parameterize_args(args)
|
231
|
+
missing_keys = missing_keys(params)
|
232
|
+
|
233
|
+
unless missing_keys.empty?
|
234
|
+
raise_generation_error(params, missing_keys)
|
235
|
+
end
|
236
|
+
|
237
|
+
@route.format params
|
238
|
+
end
|
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
|
249
|
+
|
250
|
+
def missing_keys(args)
|
251
|
+
args.select{ |part, arg| arg.nil? || arg.empty? }.keys
|
252
|
+
end
|
253
|
+
|
254
|
+
def raise_generation_error(args, missing_keys)
|
255
|
+
constraints = Hash[@route.requirements.merge(args).sort_by{|k,v| k.to_s}]
|
256
|
+
message = "No route matches #{constraints.inspect}"
|
257
|
+
message << " missing required keys: #{missing_keys.sort.inspect}"
|
258
|
+
|
259
|
+
raise ActionController::UrlGenerationError, message
|
171
260
|
end
|
172
261
|
end
|
173
262
|
|
174
|
-
def
|
175
|
-
|
263
|
+
def initialize(route, options, route_name, url_strategy)
|
264
|
+
@options = options
|
265
|
+
@segment_keys = route.segment_keys.uniq
|
266
|
+
@route = route
|
267
|
+
@url_strategy = url_strategy
|
268
|
+
@route_name = route_name
|
269
|
+
end
|
176
270
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
271
|
+
def call(t, args, inner_options)
|
272
|
+
controller_options = t.url_options
|
273
|
+
options = controller_options.merge @options
|
274
|
+
hash = handle_positional_args(controller_options,
|
275
|
+
deprecate_string_options(inner_options) || {},
|
276
|
+
args,
|
277
|
+
options,
|
278
|
+
@segment_keys)
|
183
279
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
280
|
+
t._routes.url_for(hash, route_name, url_strategy)
|
281
|
+
end
|
282
|
+
|
283
|
+
def handle_positional_args(controller_options, inner_options, args, result, path_params)
|
284
|
+
if args.size > 0
|
285
|
+
# take format into account
|
286
|
+
if path_params.include?(:format)
|
287
|
+
path_params_size = path_params.size - 1
|
288
|
+
else
|
289
|
+
path_params_size = path_params.size
|
290
|
+
end
|
188
291
|
|
189
|
-
|
292
|
+
if args.size < path_params_size
|
293
|
+
path_params -= controller_options.keys
|
294
|
+
path_params -= result.keys
|
190
295
|
end
|
191
|
-
|
192
|
-
|
193
|
-
|
296
|
+
path_params.each { |param|
|
297
|
+
value = inner_options.fetch(param) { args.shift }
|
298
|
+
|
299
|
+
unless param == :format && value.nil?
|
300
|
+
result[param] = value
|
301
|
+
end
|
302
|
+
}
|
303
|
+
end
|
304
|
+
|
305
|
+
result.merge!(inner_options)
|
194
306
|
end
|
195
307
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
# foo_url(bar, baz, bang, :sort_by => 'baz')
|
208
|
-
#
|
209
|
-
def define_url_helper(route, name, kind, options)
|
210
|
-
selector = url_helper_name(name, kind)
|
211
|
-
hash_access_method = hash_access_name(name, kind)
|
212
|
-
|
213
|
-
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
|
214
|
-
remove_possible_method :#{selector}
|
215
|
-
def #{selector}(*args)
|
216
|
-
url_for(#{hash_access_method}(*args))
|
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
|
217
319
|
end
|
218
|
-
|
219
|
-
|
320
|
+
end
|
321
|
+
options
|
220
322
|
end
|
323
|
+
end
|
324
|
+
|
325
|
+
private
|
326
|
+
# Create a url helper allowing ordered parameters to be associated
|
327
|
+
# with corresponding dynamic segments, so you can do:
|
328
|
+
#
|
329
|
+
# foo_url(bar, baz, bang)
|
330
|
+
#
|
331
|
+
# Instead of:
|
332
|
+
#
|
333
|
+
# foo_url(bar: bar, baz: baz, bang: bang)
|
334
|
+
#
|
335
|
+
# Also allow options hash, so you can do:
|
336
|
+
#
|
337
|
+
# foo_url(bar, baz, bang, sort_by: 'baz')
|
338
|
+
#
|
339
|
+
def define_url_helper(mod, route, name, opts, route_key, url_strategy)
|
340
|
+
helper = UrlHelper.create(route, opts, route_key, url_strategy)
|
341
|
+
mod.module_eval do
|
342
|
+
define_method(name) do |*args|
|
343
|
+
options = nil
|
344
|
+
options = args.pop if args.last.is_a? Hash
|
345
|
+
helper.call self, args, options
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
221
349
|
end
|
222
350
|
|
351
|
+
# strategy for building urls to send to the client
|
352
|
+
PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
|
353
|
+
FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
|
354
|
+
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
|
+
|
223
382
|
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
|
224
383
|
attr_accessor :disable_clear_and_finalize, :resources_path_names
|
225
|
-
attr_accessor :default_url_options, :request_class
|
384
|
+
attr_accessor :default_url_options, :request_class
|
226
385
|
|
227
386
|
alias :routes :set
|
228
387
|
|
@@ -232,19 +391,9 @@ module ActionDispatch
|
|
232
391
|
|
233
392
|
def initialize(request_class = ActionDispatch::Request)
|
234
393
|
self.named_routes = NamedRouteCollection.new
|
235
|
-
self.resources_path_names = self.class.default_resources_path_names
|
394
|
+
self.resources_path_names = self.class.default_resources_path_names
|
236
395
|
self.default_url_options = {}
|
237
|
-
|
238
396
|
self.request_class = request_class
|
239
|
-
@valid_conditions = {}
|
240
|
-
|
241
|
-
request_class.public_instance_methods.each { |m|
|
242
|
-
@valid_conditions[m.to_sym] = true
|
243
|
-
}
|
244
|
-
@valid_conditions[:controller] = true
|
245
|
-
@valid_conditions[:action] = true
|
246
|
-
|
247
|
-
self.valid_conditions.delete(:id)
|
248
397
|
|
249
398
|
@append = []
|
250
399
|
@prepend = []
|
@@ -252,9 +401,7 @@ module ActionDispatch
|
|
252
401
|
@finalized = false
|
253
402
|
|
254
403
|
@set = Journey::Routes.new
|
255
|
-
@router = Journey::Router.new
|
256
|
-
:parameters_key => PARAMETERS_KEY,
|
257
|
-
:request_class => request_class})
|
404
|
+
@router = Journey::Router.new @set
|
258
405
|
@formatter = Journey::Formatter.new @set
|
259
406
|
end
|
260
407
|
|
@@ -285,6 +432,7 @@ module ActionDispatch
|
|
285
432
|
mapper.instance_exec(&block)
|
286
433
|
end
|
287
434
|
end
|
435
|
+
private :eval_block
|
288
436
|
|
289
437
|
def finalize!
|
290
438
|
return if @finalized
|
@@ -300,14 +448,19 @@ module ActionDispatch
|
|
300
448
|
@prepend.each { |blk| eval_block(blk) }
|
301
449
|
end
|
302
450
|
|
303
|
-
def
|
304
|
-
|
305
|
-
named_routes.install(destinations, regenerate_code)
|
451
|
+
def dispatcher(defaults)
|
452
|
+
Routing::RouteSet::Dispatcher.new(defaults)
|
306
453
|
end
|
307
454
|
|
308
455
|
module MountedHelpers
|
456
|
+
extend ActiveSupport::Concern
|
457
|
+
include UrlFor
|
309
458
|
end
|
310
459
|
|
460
|
+
# Contains all the mounted helpers across different
|
461
|
+
# engines and the `main_app` helper for the application.
|
462
|
+
# You can include this in your classes if you want to
|
463
|
+
# access routes for other engines.
|
311
464
|
def mounted_helpers
|
312
465
|
MountedHelpers
|
313
466
|
end
|
@@ -316,45 +469,72 @@ module ActionDispatch
|
|
316
469
|
return if MountedHelpers.method_defined?(name)
|
317
470
|
|
318
471
|
routes = self
|
472
|
+
helpers = routes.url_helpers
|
473
|
+
|
319
474
|
MountedHelpers.class_eval do
|
320
475
|
define_method "_#{name}" do
|
321
|
-
RoutesProxy.new(routes,
|
476
|
+
RoutesProxy.new(routes, _routes_context, helpers)
|
322
477
|
end
|
323
478
|
end
|
324
479
|
|
325
|
-
MountedHelpers.class_eval
|
480
|
+
MountedHelpers.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
326
481
|
def #{name}
|
327
|
-
|
482
|
+
@_#{name} ||= _#{name}
|
328
483
|
end
|
329
484
|
RUBY
|
330
485
|
end
|
331
486
|
|
332
|
-
def url_helpers
|
333
|
-
|
334
|
-
routes = self
|
487
|
+
def url_helpers(supports_path = true)
|
488
|
+
routes = self
|
335
489
|
|
336
|
-
|
337
|
-
|
338
|
-
|
490
|
+
Module.new do
|
491
|
+
extend ActiveSupport::Concern
|
492
|
+
include UrlFor
|
493
|
+
|
494
|
+
# Define url_for in the singleton level so one can do:
|
495
|
+
# Rails.application.routes.url_helpers.url_for(args)
|
496
|
+
@_routes = routes
|
497
|
+
class << self
|
498
|
+
delegate :url_for, :optimize_routes_generation?, to: '@_routes'
|
499
|
+
attr_reader :_routes
|
500
|
+
def url_options; {}; end
|
501
|
+
end
|
339
502
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
routes.install_helpers(self)
|
351
|
-
singleton_class.send(:redefine_method, :_routes) { routes }
|
352
|
-
end
|
503
|
+
url_helpers = routes.named_routes.url_helpers_module
|
504
|
+
|
505
|
+
# Make named_routes available in the module singleton
|
506
|
+
# as well, so one can do:
|
507
|
+
# Rails.application.routes.url_helpers.posts_path
|
508
|
+
extend url_helpers
|
509
|
+
|
510
|
+
# Any class that includes this module will get all
|
511
|
+
# named routes...
|
512
|
+
include url_helpers
|
353
513
|
|
354
|
-
|
514
|
+
if supports_path
|
515
|
+
path_helpers = routes.named_routes.path_helpers_module
|
516
|
+
else
|
517
|
+
path_helpers = routes.named_routes.path_helpers_module(true)
|
355
518
|
end
|
356
519
|
|
357
|
-
|
520
|
+
include path_helpers
|
521
|
+
extend path_helpers
|
522
|
+
|
523
|
+
# plus a singleton class method called _routes ...
|
524
|
+
included do
|
525
|
+
singleton_class.send(:redefine_method, :_routes) { routes }
|
526
|
+
end
|
527
|
+
|
528
|
+
# And an instance method _routes. Note that
|
529
|
+
# UrlFor (included in this module) add extra
|
530
|
+
# conveniences for working with @_routes.
|
531
|
+
define_method(:_routes) { @_routes || routes }
|
532
|
+
|
533
|
+
define_method(:_generate_paths_by_default) do
|
534
|
+
supports_path
|
535
|
+
end
|
536
|
+
|
537
|
+
private :_generate_paths_by_default
|
358
538
|
end
|
359
539
|
end
|
360
540
|
|
@@ -365,16 +545,27 @@ module ActionDispatch
|
|
365
545
|
def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
|
366
546
|
raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
|
367
547
|
|
368
|
-
|
369
|
-
|
548
|
+
if name && named_routes[name]
|
549
|
+
raise ArgumentError, "Invalid route name, already in use: '#{name}' \n" \
|
550
|
+
"You may have defined two routes with the same name using the `:as` option, or " \
|
551
|
+
"you may be overriding a route already defined by a resource with the same naming. " \
|
552
|
+
"For the latter, you can restrict the routes created with `resources` as explained here: \n" \
|
553
|
+
"http://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
|
554
|
+
end
|
555
|
+
|
556
|
+
path = conditions.delete :path_info
|
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 })
|
370
560
|
|
371
561
|
route = @set.add_route(app, path, conditions, defaults, name)
|
372
562
|
named_routes[name] = route if name
|
373
563
|
route
|
374
564
|
end
|
375
565
|
|
376
|
-
def build_path(path,
|
566
|
+
def build_path(path, ast, requirements, anchor)
|
377
567
|
strexp = Journey::Router::Strexp.new(
|
568
|
+
ast,
|
378
569
|
path,
|
379
570
|
requirements,
|
380
571
|
SEPARATORS,
|
@@ -403,25 +594,26 @@ module ActionDispatch
|
|
403
594
|
end
|
404
595
|
private :build_path
|
405
596
|
|
406
|
-
def build_conditions(current_conditions,
|
597
|
+
def build_conditions(current_conditions, path_values)
|
407
598
|
conditions = current_conditions.dup
|
408
599
|
|
409
|
-
verbs = conditions[:request_method] || []
|
410
|
-
|
411
600
|
# Rack-Mount requires that :request_method be a regular expression.
|
412
601
|
# :request_method represents the HTTP verb that matches this route.
|
413
602
|
#
|
414
603
|
# Here we munge values before they get sent on to rack-mount.
|
604
|
+
verbs = conditions[:request_method] || []
|
415
605
|
unless verbs.empty?
|
416
606
|
conditions[:request_method] = %r[^#{verbs.join('|')}$]
|
417
607
|
end
|
418
|
-
conditions.delete_if { |k,v| !(req_predicates.include?(k) || path_values.include?(k)) }
|
419
608
|
|
420
|
-
conditions
|
609
|
+
conditions.keep_if do |k, _|
|
610
|
+
k == :action || k == :controller || k == :required_defaults ||
|
611
|
+
@request_class.public_method_defined?(k) || path_values.include?(k)
|
612
|
+
end
|
421
613
|
end
|
422
614
|
private :build_conditions
|
423
615
|
|
424
|
-
class Generator
|
616
|
+
class Generator
|
425
617
|
PARAMETERIZE = lambda do |name, value|
|
426
618
|
if name == :controller
|
427
619
|
value
|
@@ -434,18 +626,18 @@ module ActionDispatch
|
|
434
626
|
|
435
627
|
attr_reader :options, :recall, :set, :named_route
|
436
628
|
|
437
|
-
def initialize(options, recall, set
|
438
|
-
@named_route =
|
629
|
+
def initialize(named_route, options, recall, set)
|
630
|
+
@named_route = named_route
|
439
631
|
@options = options.dup
|
440
632
|
@recall = recall.dup
|
441
633
|
@set = set
|
442
|
-
@extras = extras
|
443
634
|
|
635
|
+
normalize_recall!
|
444
636
|
normalize_options!
|
445
637
|
normalize_controller_action_id!
|
446
638
|
use_relative_controller!
|
447
639
|
normalize_controller!
|
448
|
-
|
640
|
+
normalize_action!
|
449
641
|
end
|
450
642
|
|
451
643
|
def controller
|
@@ -458,19 +650,22 @@ module ActionDispatch
|
|
458
650
|
|
459
651
|
def use_recall_for(key)
|
460
652
|
if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
|
461
|
-
if named_route_exists?
|
462
|
-
@options[key] = @recall.delete(key) if segment_keys.include?(key)
|
463
|
-
else
|
653
|
+
if !named_route_exists? || segment_keys.include?(key)
|
464
654
|
@options[key] = @recall.delete(key)
|
465
655
|
end
|
466
656
|
end
|
467
657
|
end
|
468
658
|
|
659
|
+
# Set 'index' as default action for recall
|
660
|
+
def normalize_recall!
|
661
|
+
@recall[:action] ||= 'index'
|
662
|
+
end
|
663
|
+
|
469
664
|
def normalize_options!
|
470
665
|
# If an explicit :controller was given, always make :action explicit
|
471
666
|
# too, so that action expiry works as expected for things like
|
472
667
|
#
|
473
|
-
# generate({:
|
668
|
+
# generate({controller: 'content'}, {controller: 'content', action: 'show'})
|
474
669
|
#
|
475
670
|
# (the above is from the unit tests). In the above case, because the
|
476
671
|
# controller was explicitly given, but no action, the action is implied to
|
@@ -481,8 +676,8 @@ module ActionDispatch
|
|
481
676
|
options[:controller] = options[:controller].to_s
|
482
677
|
end
|
483
678
|
|
484
|
-
if options
|
485
|
-
options[:action] = options[:action].to_s
|
679
|
+
if options.key?(:action)
|
680
|
+
options[:action] = (options[:action] || 'index').to_s
|
486
681
|
end
|
487
682
|
end
|
488
683
|
|
@@ -492,14 +687,12 @@ module ActionDispatch
|
|
492
687
|
# :controller, :action or :id is not found, don't pull any
|
493
688
|
# more keys from the recall.
|
494
689
|
def normalize_controller_action_id!
|
495
|
-
@recall[:action] ||= 'index' if current_controller
|
496
|
-
|
497
690
|
use_recall_for(:controller) or return
|
498
691
|
use_recall_for(:action) or return
|
499
692
|
use_recall_for(:id)
|
500
693
|
end
|
501
694
|
|
502
|
-
# if the current controller is "foo/bar/baz" and :
|
695
|
+
# if the current controller is "foo/bar/baz" and controller: "baz/bat"
|
503
696
|
# is specified, the controller becomes "foo/baz/bat"
|
504
697
|
def use_relative_controller!
|
505
698
|
if !named_route && different_controller? && !controller.start_with?("/")
|
@@ -515,29 +708,17 @@ module ActionDispatch
|
|
515
708
|
@options[:controller] = controller.sub(%r{^/}, '') if controller
|
516
709
|
end
|
517
710
|
|
518
|
-
#
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
options[:action] = 'index'
|
711
|
+
# Move 'index' action from options to recall
|
712
|
+
def normalize_action!
|
713
|
+
if @options[:action] == 'index'
|
714
|
+
@recall[:action] = @options.delete(:action)
|
523
715
|
end
|
524
|
-
recall[:action] = options.delete(:action) if options[:action] == 'index'
|
525
716
|
end
|
526
717
|
|
718
|
+
# Generates a path from routes, returns [path, params].
|
719
|
+
# If no route is generated the formatter will raise ActionController::UrlGenerationError
|
527
720
|
def generate
|
528
|
-
|
529
|
-
|
530
|
-
raise_routing_error unless path
|
531
|
-
|
532
|
-
return [path, params.keys] if @extras
|
533
|
-
|
534
|
-
[path, params]
|
535
|
-
rescue Journey::Router::RoutingError
|
536
|
-
raise_routing_error
|
537
|
-
end
|
538
|
-
|
539
|
-
def raise_routing_error
|
540
|
-
raise ActionController::RoutingError, "No route matches #{options.inspect}"
|
721
|
+
@set.formatter.generate(named_route, options, recall, PARAMETERIZE)
|
541
722
|
end
|
542
723
|
|
543
724
|
def different_controller?
|
@@ -562,50 +743,78 @@ module ActionDispatch
|
|
562
743
|
end
|
563
744
|
|
564
745
|
def generate_extras(options, recall={})
|
565
|
-
|
746
|
+
route_key = options.delete :use_route
|
747
|
+
path, params = generate(route_key, options, recall)
|
748
|
+
return path, params.keys
|
566
749
|
end
|
567
750
|
|
568
|
-
def generate(options, recall = {}
|
569
|
-
Generator.new(options, recall, self
|
751
|
+
def generate(route_key, options, recall = {})
|
752
|
+
Generator.new(route_key, options, recall, self).generate
|
570
753
|
end
|
754
|
+
private :generate
|
571
755
|
|
572
756
|
RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
|
573
|
-
:trailing_slash, :anchor, :params, :only_path, :script_name
|
757
|
+
:trailing_slash, :anchor, :params, :only_path, :script_name,
|
758
|
+
:original_script_name, :relative_url_root]
|
574
759
|
|
575
|
-
def
|
576
|
-
|
760
|
+
def optimize_routes_generation?
|
761
|
+
default_url_options.empty?
|
762
|
+
end
|
763
|
+
|
764
|
+
def find_script_name(options)
|
765
|
+
options.delete(:script_name) || find_relative_url_root(options) || ''
|
766
|
+
end
|
767
|
+
|
768
|
+
def find_relative_url_root(options)
|
769
|
+
options.delete(:relative_url_root) || relative_url_root
|
577
770
|
end
|
578
771
|
|
579
|
-
def
|
580
|
-
|
581
|
-
|
772
|
+
def path_for(options, route_name = nil)
|
773
|
+
url_for(options, route_name, PATH)
|
774
|
+
end
|
582
775
|
|
583
|
-
|
776
|
+
# The +options+ argument must be a hash whose keys are *symbols*.
|
777
|
+
def url_for(options, route_name = nil, url_strategy = UNKNOWN)
|
778
|
+
options = default_url_options.merge options
|
584
779
|
|
585
|
-
user
|
586
|
-
path_segments = options.delete(:_path_segments)
|
587
|
-
script_name = options.delete(:script_name)
|
780
|
+
user = password = nil
|
588
781
|
|
589
|
-
|
782
|
+
if options[:user] && options[:password]
|
783
|
+
user = options.delete :user
|
784
|
+
password = options.delete :password
|
785
|
+
end
|
590
786
|
|
591
|
-
|
592
|
-
path_options = yield(path_options) if block_given?
|
787
|
+
recall = options.delete(:_recall) { {} }
|
593
788
|
|
594
|
-
|
595
|
-
|
596
|
-
|
789
|
+
original_script_name = options.delete(:original_script_name)
|
790
|
+
script_name = find_script_name options
|
791
|
+
|
792
|
+
if original_script_name
|
793
|
+
script_name = original_script_name + script_name
|
794
|
+
end
|
795
|
+
|
796
|
+
path_options = options.dup
|
797
|
+
RESERVED_OPTIONS.each { |ro| path_options.delete ro }
|
798
|
+
|
799
|
+
path, params = generate(route_name, path_options, recall)
|
800
|
+
|
801
|
+
if options.key? :params
|
802
|
+
params.merge! options[:params]
|
803
|
+
end
|
597
804
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
805
|
+
options[:path] = path
|
806
|
+
options[:script_name] = script_name
|
807
|
+
options[:params] = params
|
808
|
+
options[:user] = user
|
809
|
+
options[:password] = password
|
810
|
+
|
811
|
+
url_strategy.call options
|
604
812
|
end
|
605
813
|
|
606
814
|
def call(env)
|
607
|
-
|
608
|
-
|
815
|
+
req = request_class.new(env)
|
816
|
+
req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
|
817
|
+
@router.serve(req)
|
609
818
|
end
|
610
819
|
|
611
820
|
def recognize_path(path, environment = {})
|
@@ -614,54 +823,38 @@ module ActionDispatch
|
|
614
823
|
extras = environment[:extras] || {}
|
615
824
|
|
616
825
|
begin
|
617
|
-
env = Rack::MockRequest.env_for(path, {:method => method
|
826
|
+
env = Rack::MockRequest.env_for(path, {:method => method})
|
618
827
|
rescue URI::InvalidURIError => e
|
619
828
|
raise ActionController::RoutingError, e.message
|
620
829
|
end
|
621
830
|
|
622
|
-
req =
|
623
|
-
@router.recognize(req) do |route,
|
831
|
+
req = request_class.new(env)
|
832
|
+
@router.recognize(req) do |route, params|
|
833
|
+
params.merge!(extras)
|
624
834
|
params.each do |key, value|
|
625
835
|
if value.is_a?(String)
|
626
|
-
value = value.dup.force_encoding(Encoding::BINARY)
|
836
|
+
value = value.dup.force_encoding(Encoding::BINARY)
|
627
837
|
params[key] = URI.parser.unescape(value)
|
628
838
|
end
|
629
839
|
end
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
840
|
+
old_params = req.path_parameters
|
841
|
+
req.path_parameters = old_params.merge params
|
842
|
+
app = route.app
|
843
|
+
if app.matches?(req) && app.dispatcher?
|
844
|
+
dispatcher = app.app
|
845
|
+
|
846
|
+
if dispatcher.controller(params, false)
|
847
|
+
dispatcher.prepare_params!(params)
|
848
|
+
return params
|
849
|
+
else
|
850
|
+
raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller"
|
851
|
+
end
|
639
852
|
end
|
640
853
|
end
|
641
854
|
|
642
855
|
raise ActionController::RoutingError, "No route matches #{path.inspect}"
|
643
856
|
end
|
644
|
-
|
645
|
-
private
|
646
|
-
|
647
|
-
def extract_authentication(options)
|
648
|
-
if options[:user] && options[:password]
|
649
|
-
[options.delete(:user), options.delete(:password)]
|
650
|
-
else
|
651
|
-
nil
|
652
|
-
end
|
653
|
-
end
|
654
|
-
|
655
|
-
def handle_positional_args(options)
|
656
|
-
return unless args = options.delete(:_positional_args)
|
657
|
-
|
658
|
-
keys = options.delete(:_positional_keys)
|
659
|
-
keys -= options.keys if args.size < keys.size - 1 # take format into account
|
660
|
-
|
661
|
-
# Tell url_for to skip default_url_options
|
662
|
-
options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }])
|
663
|
-
end
|
664
|
-
|
665
857
|
end
|
858
|
+
# :startdoc:
|
666
859
|
end
|
667
860
|
end
|