actionpack 7.1.5.1 → 7.2.0.beta1
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 +61 -642
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +70 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +12 -13
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +74 -72
- data/lib/action_controller/base.rb +155 -117
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/allow_browser.rb +119 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +188 -174
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +64 -55
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +214 -203
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +113 -107
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +483 -478
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +58 -57
- data/lib/action_controller/railtie.rb +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +146 -126
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +48 -59
- data/lib/action_dispatch/http/filter_parameters.rb +13 -14
- data/lib/action_dispatch/http/filter_redirect.rb +15 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
- data/lib/action_dispatch/http/mime_type.rb +25 -21
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +26 -36
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +75 -95
- data/lib/action_dispatch/http/response.rb +61 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +2 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +2 -0
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
- data/lib/action_dispatch/middleware/ssl.rb +43 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -3
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +6 -4
- data/lib/action_dispatch/routing/mapper.rb +623 -625
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +60 -46
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +4 -2
- data/lib/action_dispatch/system_testing/driver.rb +2 -0
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +22 -32
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +33 -16
@@ -1,104 +1,111 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module Routing
|
5
|
-
#
|
7
|
+
# # Action Dispatch Routing PolymorphicRoutes
|
6
8
|
#
|
7
|
-
# Polymorphic URL helpers are methods for smart resolution to a named route call
|
8
|
-
# given an Active Record model instance. They are to be used in combination
|
9
|
-
# ActionController::Resources.
|
9
|
+
# Polymorphic URL helpers are methods for smart resolution to a named route call
|
10
|
+
# when given an Active Record model instance. They are to be used in combination
|
11
|
+
# with ActionController::Resources.
|
10
12
|
#
|
11
|
-
# These methods are useful when you want to generate the correct URL or path to
|
12
|
-
# resource without having to know the exact type of the record in
|
13
|
+
# These methods are useful when you want to generate the correct URL or path to
|
14
|
+
# a RESTful resource without having to know the exact type of the record in
|
15
|
+
# question.
|
13
16
|
#
|
14
|
-
# Nested resources and/or namespaces are also supported, as illustrated in the
|
17
|
+
# Nested resources and/or namespaces are also supported, as illustrated in the
|
18
|
+
# example:
|
15
19
|
#
|
16
|
-
#
|
20
|
+
# polymorphic_url([:admin, @article, @comment])
|
17
21
|
#
|
18
22
|
# results in:
|
19
23
|
#
|
20
|
-
#
|
24
|
+
# admin_article_comment_url(@article, @comment)
|
25
|
+
#
|
26
|
+
# ## Usage within the framework
|
21
27
|
#
|
22
|
-
#
|
28
|
+
# Polymorphic URL helpers are used in a number of places throughout the Rails
|
29
|
+
# framework:
|
23
30
|
#
|
24
|
-
#
|
31
|
+
# * `url_for`, so you can use it with a record as the argument, e.g.
|
32
|
+
# `url_for(@article)`;
|
33
|
+
# * ActionView::Helpers::FormHelper uses `polymorphic_path`, so you can write
|
34
|
+
# `form_for(@article)` without having to specify `:url` parameter for the
|
35
|
+
# form action;
|
36
|
+
# * `redirect_to` (which, in fact, uses `url_for`) so you can write
|
37
|
+
# `redirect_to(post)` in your controllers;
|
38
|
+
# * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly
|
39
|
+
# specify URLs for feed entries.
|
25
40
|
#
|
26
|
-
# * <tt>url_for</tt>, so you can use it with a record as the argument, e.g.
|
27
|
-
# <tt>url_for(@article)</tt>;
|
28
|
-
# * ActionView::Helpers::FormHelper uses <tt>polymorphic_path</tt>, so you can write
|
29
|
-
# <tt>form_for(@article)</tt> without having to specify <tt>:url</tt> parameter for the form
|
30
|
-
# action;
|
31
|
-
# * <tt>redirect_to</tt> (which, in fact, uses <tt>url_for</tt>) so you can write
|
32
|
-
# <tt>redirect_to(post)</tt> in your controllers;
|
33
|
-
# * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs
|
34
|
-
# for feed entries.
|
35
41
|
#
|
36
|
-
#
|
42
|
+
# ## Prefixed polymorphic helpers
|
37
43
|
#
|
38
|
-
# In addition to
|
39
|
-
#
|
40
|
-
#
|
44
|
+
# In addition to `polymorphic_url` and `polymorphic_path` methods, a number of
|
45
|
+
# prefixed helpers are available as a shorthand to `action: "..."` in options.
|
46
|
+
# Those are:
|
47
|
+
#
|
48
|
+
# * `edit_polymorphic_url`, `edit_polymorphic_path`
|
49
|
+
# * `new_polymorphic_url`, `new_polymorphic_path`
|
41
50
|
#
|
42
|
-
# * <tt>edit_polymorphic_url</tt>, <tt>edit_polymorphic_path</tt>
|
43
|
-
# * <tt>new_polymorphic_url</tt>, <tt>new_polymorphic_path</tt>
|
44
51
|
#
|
45
52
|
# Example usage:
|
46
53
|
#
|
47
|
-
#
|
48
|
-
#
|
54
|
+
# edit_polymorphic_path(@post) # => "/posts/1/edit"
|
55
|
+
# polymorphic_path(@post, format: :pdf) # => "/posts/1.pdf"
|
49
56
|
#
|
50
|
-
#
|
57
|
+
# ## Usage with mounted engines
|
51
58
|
#
|
52
59
|
# If you are using a mounted engine and you need to use a polymorphic_url
|
53
60
|
# pointing at the engine's routes, pass in the engine's route proxy as the first
|
54
61
|
# argument to the method. For example:
|
55
62
|
#
|
56
|
-
#
|
57
|
-
#
|
63
|
+
# polymorphic_url([blog, @post]) # calls blog.post_path(@post)
|
64
|
+
# form_for([blog, @post]) # => "/blog/posts/1"
|
58
65
|
#
|
59
66
|
module PolymorphicRoutes
|
60
|
-
# Constructs a call to a named RESTful route for the given record and returns
|
61
|
-
# resulting URL string. For example:
|
67
|
+
# Constructs a call to a named RESTful route for the given record and returns
|
68
|
+
# the resulting URL string. For example:
|
69
|
+
#
|
70
|
+
# # calls post_url(post)
|
71
|
+
# polymorphic_url(post) # => "http://example.com/posts/1"
|
72
|
+
# polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
|
73
|
+
# polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
|
74
|
+
# polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
|
75
|
+
# polymorphic_url(Comment) # => "http://example.com/comments"
|
62
76
|
#
|
63
|
-
#
|
64
|
-
# polymorphic_url(post) # => "http://example.com/posts/1"
|
65
|
-
# polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
|
66
|
-
# polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
|
67
|
-
# polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
|
68
|
-
# polymorphic_url(Comment) # => "http://example.com/comments"
|
77
|
+
# #### Options
|
69
78
|
#
|
70
|
-
#
|
79
|
+
# * `:action` - Specifies the action prefix for the named route: `:new` or
|
80
|
+
# `:edit`. Default is no prefix.
|
81
|
+
# * `:routing_type` - Allowed values are `:path` or `:url`. Default is `:url`.
|
71
82
|
#
|
72
|
-
# * <tt>:action</tt> - Specifies the action prefix for the named route:
|
73
|
-
# <tt>:new</tt> or <tt>:edit</tt>. Default is no prefix.
|
74
|
-
# * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
|
75
|
-
# Default is <tt>:url</tt>.
|
76
83
|
#
|
77
|
-
# Also includes all the options from
|
78
|
-
#
|
79
|
-
# is given below:
|
84
|
+
# Also includes all the options from `url_for`. These include such things as
|
85
|
+
# `:anchor` or `:trailing_slash`. Example usage is given below:
|
80
86
|
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
87
|
+
# polymorphic_url([blog, post], anchor: 'my_anchor')
|
88
|
+
# # => "http://example.com/blogs/1/posts/1#my_anchor"
|
89
|
+
# polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
|
90
|
+
# # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
|
85
91
|
#
|
86
|
-
# For all of these options, see the documentation for
|
92
|
+
# For all of these options, see the documentation for
|
93
|
+
# [url_for](rdoc-ref:ActionDispatch::Routing::UrlFor).
|
87
94
|
#
|
88
|
-
#
|
95
|
+
# #### Functionality
|
89
96
|
#
|
90
|
-
#
|
91
|
-
#
|
97
|
+
# # an Article record
|
98
|
+
# polymorphic_url(record) # same as article_url(record)
|
92
99
|
#
|
93
|
-
#
|
94
|
-
#
|
100
|
+
# # a Comment record
|
101
|
+
# polymorphic_url(record) # same as comment_url(record)
|
95
102
|
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
103
|
+
# # it recognizes new records and maps to the collection
|
104
|
+
# record = Comment.new
|
105
|
+
# polymorphic_url(record) # same as comments_url()
|
99
106
|
#
|
100
|
-
#
|
101
|
-
#
|
107
|
+
# # the class of a record will also map to the collection
|
108
|
+
# polymorphic_url(Comment) # same as comments_url()
|
102
109
|
#
|
103
110
|
def polymorphic_url(record_or_hash_or_array, options = {})
|
104
111
|
if Hash === record_or_hash_or_array
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/array/extract_options"
|
4
6
|
require "rack/utils"
|
5
7
|
require "action_controller/metal/exceptions"
|
@@ -146,55 +148,58 @@ module ActionDispatch
|
|
146
148
|
module Redirection
|
147
149
|
# Redirect any path to another path:
|
148
150
|
#
|
149
|
-
#
|
151
|
+
# get "/stories" => redirect("/posts")
|
150
152
|
#
|
151
|
-
# This will redirect the user, while ignoring certain parts of the request,
|
152
|
-
#
|
153
|
+
# This will redirect the user, while ignoring certain parts of the request,
|
154
|
+
# including query string, etc. `/stories`, `/stories?foo=bar`, etc all redirect
|
155
|
+
# to `/posts`.
|
153
156
|
#
|
154
|
-
# The redirect will use a
|
155
|
-
#
|
157
|
+
# The redirect will use a `301 Moved Permanently` status code by default. This
|
158
|
+
# can be overridden with the `:status` option:
|
156
159
|
#
|
157
|
-
#
|
160
|
+
# get "/stories" => redirect("/posts", status: 307)
|
158
161
|
#
|
159
162
|
# You can also use interpolation in the supplied redirect argument:
|
160
163
|
#
|
161
|
-
#
|
164
|
+
# get 'docs/:article', to: redirect('/wiki/%{article}')
|
162
165
|
#
|
163
|
-
# Note that if you return a path without a leading slash then the URL is
|
164
|
-
# current SCRIPT_NAME environment variable. This is typically
|
165
|
-
# a mounted engine or where the application is
|
166
|
+
# Note that if you return a path without a leading slash then the URL is
|
167
|
+
# prefixed with the current SCRIPT_NAME environment variable. This is typically
|
168
|
+
# '/' but may be different in a mounted engine or where the application is
|
169
|
+
# deployed to a subdirectory of a website.
|
166
170
|
#
|
167
171
|
# Alternatively you can use one of the other syntaxes:
|
168
172
|
#
|
169
|
-
# The block version of redirect allows for the easy encapsulation of any logic
|
170
|
-
# the redirect in question. Either the params and request are
|
171
|
-
# params, depending of how many arguments your
|
172
|
-
# return value.
|
173
|
+
# The block version of redirect allows for the easy encapsulation of any logic
|
174
|
+
# associated with the redirect in question. Either the params and request are
|
175
|
+
# supplied as arguments, or just params, depending of how many arguments your
|
176
|
+
# block accepts. A string is required as a return value.
|
173
177
|
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
+
# get 'jokes/:number', to: redirect { |params, request|
|
179
|
+
# path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp")
|
180
|
+
# "http://#{request.host_with_port}/#{path}"
|
181
|
+
# }
|
178
182
|
#
|
179
|
-
# Note that the
|
180
|
-
# the block to
|
183
|
+
# Note that the `do end` syntax for the redirect block wouldn't work, as Ruby
|
184
|
+
# would pass the block to `get` instead of `redirect`. Use `{ ... }` instead.
|
181
185
|
#
|
182
|
-
# The options version of redirect allows you to supply only the parts of the URL
|
183
|
-
# to change, it also supports interpolation of the path similar to
|
186
|
+
# The options version of redirect allows you to supply only the parts of the URL
|
187
|
+
# which need to change, it also supports interpolation of the path similar to
|
188
|
+
# the first example.
|
184
189
|
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
#
|
190
|
+
# get 'stores/:name', to: redirect(subdomain: 'stores', path: '/%{name}')
|
191
|
+
# get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}')
|
192
|
+
# get '/stories', to: redirect(path: '/posts')
|
188
193
|
#
|
189
|
-
# This will redirect the user, while changing only the specified parts of the
|
190
|
-
# for example the
|
191
|
-
#
|
194
|
+
# This will redirect the user, while changing only the specified parts of the
|
195
|
+
# request, for example the `path` option in the last example. `/stories`,
|
196
|
+
# `/stories?foo=bar`, redirect to `/posts` and `/posts?foo=bar` respectively.
|
192
197
|
#
|
193
|
-
# Finally, an object which responds to call can be supplied to redirect,
|
194
|
-
# common redirect routes. The call method must accept two
|
195
|
-
# a string.
|
198
|
+
# Finally, an object which responds to call can be supplied to redirect,
|
199
|
+
# allowing you to reuse common redirect routes. The call method must accept two
|
200
|
+
# arguments, params and request, and return a string.
|
196
201
|
#
|
197
|
-
#
|
202
|
+
# get 'accounts/:name' => redirect(SubdomainRedirector.new('api'))
|
198
203
|
#
|
199
204
|
def redirect(*args, &block)
|
200
205
|
options = args.extract_options!
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_dispatch/journey"
|
4
6
|
require "active_support/core_ext/object/to_query"
|
5
7
|
require "active_support/core_ext/module/redefine_method"
|
@@ -10,12 +12,28 @@ require "action_dispatch/routing/endpoint"
|
|
10
12
|
|
11
13
|
module ActionDispatch
|
12
14
|
module Routing
|
13
|
-
#
|
15
|
+
# The RouteSet contains a collection of Route instances, representing the routes
|
16
|
+
# typically defined in `config/routes.rb`.
|
14
17
|
class RouteSet
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
18
|
+
# Returns a Route matching the given requirements, or `nil` if none are found.
|
19
|
+
#
|
20
|
+
# This is intended for use by tools such as Language Servers.
|
21
|
+
#
|
22
|
+
# Given the routes are defined as:
|
23
|
+
#
|
24
|
+
# resources :posts
|
25
|
+
#
|
26
|
+
# Then the following will return the Route for the `show` action:
|
27
|
+
#
|
28
|
+
# Rails.application.routes.from_requirements(controller: "posts", action: "show")
|
29
|
+
def from_requirements(requirements)
|
30
|
+
routes.find { |route| route.requirements == requirements }
|
31
|
+
end
|
32
|
+
# :stopdoc:
|
33
|
+
|
34
|
+
# Since the router holds references to many parts of the system like engines,
|
35
|
+
# controllers and the application itself, inspecting the route set can actually
|
36
|
+
# be really slow, therefore we default alias inspect to to_s.
|
19
37
|
alias inspect to_s
|
20
38
|
|
21
39
|
class Dispatcher < Routing::Endpoint
|
@@ -144,8 +162,8 @@ module ActionDispatch
|
|
144
162
|
routes.length
|
145
163
|
end
|
146
164
|
|
147
|
-
# Given a
|
148
|
-
#
|
165
|
+
# Given a `name`, defines name_path and name_url helpers. Used by 'direct',
|
166
|
+
# 'resolve', and 'polymorphic' route helpers.
|
149
167
|
def add_url_helper(name, defaults, &block)
|
150
168
|
helper = CustomUrlHelper.new(name, defaults, &block)
|
151
169
|
path_name = :"#{name}_path"
|
@@ -301,18 +319,18 @@ module ActionDispatch
|
|
301
319
|
end
|
302
320
|
|
303
321
|
private
|
304
|
-
# Create a URL helper allowing ordered parameters to be associated
|
305
|
-
#
|
322
|
+
# Create a URL helper allowing ordered parameters to be associated with
|
323
|
+
# corresponding dynamic segments, so you can do:
|
306
324
|
#
|
307
|
-
#
|
325
|
+
# foo_url(bar, baz, bang)
|
308
326
|
#
|
309
327
|
# Instead of:
|
310
328
|
#
|
311
|
-
#
|
329
|
+
# foo_url(bar: bar, baz: baz, bang: bang)
|
312
330
|
#
|
313
331
|
# Also allow options hash, so you can do:
|
314
332
|
#
|
315
|
-
#
|
333
|
+
# foo_url(bar, baz, bang, sort_by: 'baz')
|
316
334
|
#
|
317
335
|
def define_url_helper(mod, name, helper, url_strategy)
|
318
336
|
mod.define_method(name) do |*args|
|
@@ -386,6 +404,7 @@ module ActionDispatch
|
|
386
404
|
def eager_load!
|
387
405
|
router.eager_load!
|
388
406
|
routes.each(&:eager_load!)
|
407
|
+
formatter.eager_load!
|
389
408
|
nil
|
390
409
|
end
|
391
410
|
|
@@ -470,10 +489,9 @@ module ActionDispatch
|
|
470
489
|
include UrlFor
|
471
490
|
end
|
472
491
|
|
473
|
-
# Contains all the mounted helpers across different
|
474
|
-
#
|
475
|
-
#
|
476
|
-
# access routes for other engines.
|
492
|
+
# Contains all the mounted helpers across different engines and the `main_app`
|
493
|
+
# helper for the application. You can include this in your classes if you want
|
494
|
+
# to access routes for other engines.
|
477
495
|
def mounted_helpers
|
478
496
|
MountedHelpers
|
479
497
|
end
|
@@ -563,13 +581,11 @@ module ActionDispatch
|
|
563
581
|
|
564
582
|
url_helpers = routes.named_routes.url_helpers_module
|
565
583
|
|
566
|
-
# Make named_routes available in the module singleton
|
567
|
-
# as well, so one can do:
|
584
|
+
# Make named_routes available in the module singleton as well, so one can do:
|
568
585
|
# Rails.application.routes.url_helpers.posts_path
|
569
586
|
extend url_helpers
|
570
587
|
|
571
|
-
# Any class that includes this module will get all
|
572
|
-
# named routes...
|
588
|
+
# Any class that includes this module will get all named routes...
|
573
589
|
include url_helpers
|
574
590
|
|
575
591
|
if supports_path
|
@@ -584,9 +600,8 @@ module ActionDispatch
|
|
584
600
|
redefine_singleton_method(:_routes) { routes }
|
585
601
|
end
|
586
602
|
|
587
|
-
# And an instance method _routes. Note that
|
588
|
-
#
|
589
|
-
# conveniences for working with @_routes.
|
603
|
+
# And an instance method _routes. Note that UrlFor (included in this module) add
|
604
|
+
# extra conveniences for working with @_routes.
|
590
605
|
define_method(:_routes) { @_routes || routes }
|
591
606
|
|
592
607
|
define_method(:_generate_paths_by_default) do
|
@@ -595,12 +610,12 @@ module ActionDispatch
|
|
595
610
|
|
596
611
|
private :_generate_paths_by_default
|
597
612
|
|
598
|
-
# If the module is included more than once (for example, in a subclass
|
599
|
-
#
|
600
|
-
#
|
601
|
-
#
|
602
|
-
#
|
603
|
-
#
|
613
|
+
# If the module is included more than once (for example, in a subclass of an
|
614
|
+
# ancestor that includes the module), ensure that the `_routes` singleton and
|
615
|
+
# instance methods return the desired route set by including a new copy of the
|
616
|
+
# module (recursively if necessary). Note that this method is called for each
|
617
|
+
# inclusion, whereas the above `included` block is run only for the initial
|
618
|
+
# inclusion of each copy.
|
604
619
|
def self.included(base)
|
605
620
|
super
|
606
621
|
if base.respond_to?(:_routes) && !base._routes.equal?(@_proxy._routes)
|
@@ -716,14 +731,14 @@ module ActionDispatch
|
|
716
731
|
end
|
717
732
|
|
718
733
|
def normalize_options!
|
719
|
-
# If an explicit :controller was given, always make :action explicit
|
720
|
-
#
|
734
|
+
# If an explicit :controller was given, always make :action explicit too, so
|
735
|
+
# that action expiry works as expected for things like
|
721
736
|
#
|
722
|
-
#
|
737
|
+
# generate({controller: 'content'}, {controller: 'content', action: 'show'})
|
723
738
|
#
|
724
|
-
# (the above is from the unit tests). In the above case, because the
|
725
|
-
#
|
726
|
-
#
|
739
|
+
# (the above is from the unit tests). In the above case, because the controller
|
740
|
+
# was explicitly given, but no action, the action is implied to be "index", not
|
741
|
+
# the recalled action of "show".
|
727
742
|
|
728
743
|
if options[:controller]
|
729
744
|
options[:action] ||= "index"
|
@@ -735,10 +750,9 @@ module ActionDispatch
|
|
735
750
|
end
|
736
751
|
end
|
737
752
|
|
738
|
-
# This pulls :controller, :action, and :id out of the recall.
|
739
|
-
#
|
740
|
-
#
|
741
|
-
# :controller, :action or :id is not found, don't pull any
|
753
|
+
# This pulls :controller, :action, and :id out of the recall. The recall key is
|
754
|
+
# only used if there is no key in the options or if the key in the options is
|
755
|
+
# identical. If any of :controller, :action or :id is not found, don't pull any
|
742
756
|
# more keys from the recall.
|
743
757
|
def normalize_controller_action_id!
|
744
758
|
use_recall_for(:controller) || return
|
@@ -746,8 +760,8 @@ module ActionDispatch
|
|
746
760
|
use_recall_for(:id)
|
747
761
|
end
|
748
762
|
|
749
|
-
# if the current controller is "foo/bar/baz" and controller: "baz/bat"
|
750
|
-
#
|
763
|
+
# if the current controller is "foo/bar/baz" and controller: "baz/bat" is
|
764
|
+
# specified, the controller becomes "foo/baz/bat"
|
751
765
|
def use_relative_controller!
|
752
766
|
if !named_route && different_controller? && !controller.start_with?("/")
|
753
767
|
old_parts = current_controller.split("/")
|
@@ -789,8 +803,8 @@ module ActionDispatch
|
|
789
803
|
end
|
790
804
|
end
|
791
805
|
|
792
|
-
# Generate the path indicated by the arguments, and return an array of
|
793
|
-
#
|
806
|
+
# Generate the path indicated by the arguments, and return an array of the keys
|
807
|
+
# that were not used to generate it.
|
794
808
|
def extra_keys(options, recall = {})
|
795
809
|
generate_extras(options, recall).last
|
796
810
|
end
|
@@ -827,7 +841,7 @@ module ActionDispatch
|
|
827
841
|
url_for(options, route_name, PATH, nil, reserved)
|
828
842
|
end
|
829
843
|
|
830
|
-
# The
|
844
|
+
# The `options` argument must be a hash whose keys are **symbols**.
|
831
845
|
def url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS)
|
832
846
|
options = default_url_options.merge options
|
833
847
|
|
@@ -860,7 +874,7 @@ module ActionDispatch
|
|
860
874
|
params = route_with_params.params
|
861
875
|
|
862
876
|
if options.key? :params
|
863
|
-
if options[:params]
|
877
|
+
if options[:params].respond_to?(:to_hash)
|
864
878
|
params.merge! options[:params]
|
865
879
|
else
|
866
880
|
params[:params] = options[:params]
|
@@ -903,7 +917,7 @@ module ActionDispatch
|
|
903
917
|
params.each do |key, value|
|
904
918
|
if value.is_a?(String)
|
905
919
|
value = value.dup.force_encoding(Encoding::BINARY)
|
906
|
-
params[key] =
|
920
|
+
params[key] = URI::DEFAULT_PARSER.unescape(value)
|
907
921
|
end
|
908
922
|
end
|
909
923
|
req.path_parameters = params
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/array/extract_options"
|
4
6
|
|
5
7
|
module ActionDispatch
|
@@ -46,10 +48,10 @@ module ActionDispatch
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
# Keeps the part of the script name provided by the global
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
51
|
+
# Keeps the part of the script name provided by the global context via
|
52
|
+
# [ENV]("SCRIPT_NAME"), which `mount` doesn't know about since it depends on the
|
53
|
+
# specific request, but use our script name resolver for the mount point
|
54
|
+
# dependent part.
|
53
55
|
def merge_script_names(previous_script_name, new_script_name)
|
54
56
|
return new_script_name unless previous_script_name
|
55
57
|
|