actionpack 6.1.3.1 → 7.0.0.alpha1
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 +102 -370
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +7 -21
- data/lib/abstract_controller/caching/fragments.rb +2 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +9 -8
- data/lib/abstract_controller/collector.rb +4 -2
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +3 -2
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/translation.rb +0 -2
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +38 -1
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -13
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +19 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +16 -16
- data/lib/action_controller/metal/instrumentation.rb +55 -52
- data/lib/action_controller/metal/live.rb +52 -3
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/params_wrapper.rb +10 -9
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/query_tags.rb +16 -0
- data/lib/action_controller/metal/redirecting.rb +50 -16
- data/lib/action_controller/metal/rendering.rb +7 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +64 -20
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +1 -3
- data/lib/action_controller/metal/strong_parameters.rb +24 -28
- data/lib/action_controller/metal/testing.rb +0 -2
- data/lib/action_controller/metal.rb +7 -10
- data/lib/action_controller/railtie.rb +42 -5
- data/lib/action_controller/test_case.rb +9 -2
- data/lib/action_controller.rb +2 -5
- data/lib/action_dispatch/http/cache.rb +18 -12
- data/lib/action_dispatch/http/content_security_policy.rb +39 -35
- data/lib/action_dispatch/http/filter_parameters.rb +5 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
- data/lib/action_dispatch/http/mime_type.rb +9 -11
- data/lib/action_dispatch/http/parameters.rb +4 -4
- data/lib/action_dispatch/http/permissions_policy.rb +1 -1
- data/lib/action_dispatch/http/request.rb +10 -19
- data/lib/action_dispatch/http/response.rb +3 -3
- data/lib/action_dispatch/http/url.rb +9 -10
- data/lib/action_dispatch/journey/formatter.rb +2 -2
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +22 -13
- data/lib/action_dispatch/journey/route.rb +5 -12
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +1 -1
- data/lib/action_dispatch/journey/routes.rb +3 -3
- data/lib/action_dispatch/journey/visitors.rb +1 -1
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
- data/lib/action_dispatch/middleware/cookies.rb +7 -3
- data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
- data/lib/action_dispatch/middleware/flash.rb +9 -11
- data/lib/action_dispatch/middleware/host_authorization.rb +10 -18
- data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +7 -9
- data/lib/action_dispatch/middleware/stack.rb +50 -9
- data/lib/action_dispatch/middleware/static.rb +2 -5
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +43 -13
- data/lib/action_dispatch/routing/mapper.rb +44 -72
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -4
- data/lib/action_dispatch/routing/redirection.rb +0 -2
- data/lib/action_dispatch/routing/route_set.rb +9 -6
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +1 -2
- data/lib/action_dispatch/routing.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +5 -5
- data/lib/action_dispatch/system_testing/driver.rb +24 -4
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
- data/lib/action_dispatch/testing/assertions.rb +2 -5
- data/lib/action_dispatch/testing/integration.rb +6 -8
- data/lib/action_dispatch/testing/test_process.rb +12 -9
- data/lib/action_dispatch.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +18 -17
@@ -1,8 +1,8 @@
|
|
1
|
-
<header>
|
1
|
+
<header role="banner">
|
2
2
|
<h1>No template for interactive request</h1>
|
3
3
|
</header>
|
4
4
|
|
5
|
-
<
|
5
|
+
<main id="container">
|
6
6
|
<h2><%= h @exception.message %></h2>
|
7
7
|
|
8
8
|
<p class="summary">
|
@@ -16,4 +16,4 @@
|
|
16
16
|
since we expect an HTML template
|
17
17
|
to be rendered for such requests. If that's the case, carry on.
|
18
18
|
</p>
|
19
|
-
</
|
19
|
+
</main>
|
@@ -1,11 +1,11 @@
|
|
1
|
-
<header>
|
1
|
+
<header role="banner">
|
2
2
|
<h1>Template is missing</h1>
|
3
3
|
</header>
|
4
4
|
|
5
|
-
<
|
5
|
+
<main role="main" id="container">
|
6
6
|
<h2><%= h @exception.message %></h2>
|
7
7
|
|
8
8
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
9
9
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
10
10
|
<%= render template: "rescues/_request_and_response" %>
|
11
|
-
</
|
11
|
+
</main>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
<header>
|
1
|
+
<header role="banner">
|
2
2
|
<h1>Routing Error</h1>
|
3
3
|
</header>
|
4
|
-
<
|
4
|
+
<main role="main" id="container">
|
5
5
|
<h2><%= h @exception.message %></h2>
|
6
6
|
<% unless @exception.failures.empty? %>
|
7
7
|
<p>
|
@@ -29,4 +29,4 @@
|
|
29
29
|
<% end %>
|
30
30
|
|
31
31
|
<%= render template: "rescues/_request_and_response" %>
|
32
|
-
</
|
32
|
+
</main>
|
@@ -1,11 +1,11 @@
|
|
1
|
-
<header>
|
1
|
+
<header role="banner">
|
2
2
|
<h1>
|
3
3
|
<%= @exception.cause.class.to_s %> in
|
4
4
|
<%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
|
5
5
|
</h1>
|
6
6
|
</header>
|
7
7
|
|
8
|
-
<
|
8
|
+
<main role="main" id="container">
|
9
9
|
<p>
|
10
10
|
Showing <i><%= @exception.file_name %></i> where line <b>#<%= @exception.line_number %></b> raised:
|
11
11
|
</p>
|
@@ -17,4 +17,4 @@
|
|
17
17
|
|
18
18
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
19
19
|
<%= render template: "rescues/_request_and_response" %>
|
20
|
-
</
|
20
|
+
</main>
|
@@ -51,22 +51,13 @@
|
|
51
51
|
}
|
52
52
|
|
53
53
|
@media (prefers-color-scheme: dark) {
|
54
|
-
body {
|
55
|
-
background-color: #222;
|
56
|
-
color: #ECECEC;
|
57
|
-
}
|
58
|
-
|
59
54
|
#route_table tbody tr:nth-child(odd) {
|
60
|
-
background: #
|
61
|
-
}
|
62
|
-
|
63
|
-
#route_table tbody tr:nth-child(even) {
|
64
|
-
background: #444;
|
55
|
+
background: #282828;
|
65
56
|
}
|
66
57
|
|
67
|
-
#route_table tbody.exact_matches,
|
68
|
-
#route_table tbody.fuzzy_matches {
|
69
|
-
|
58
|
+
#route_table tbody.exact_matches tr,
|
59
|
+
#route_table tbody.fuzzy_matches tr {
|
60
|
+
background: DarkSlateGrey;
|
70
61
|
}
|
71
62
|
}
|
72
63
|
<% end %>
|
@@ -104,7 +95,7 @@
|
|
104
95
|
</tbody>
|
105
96
|
</table>
|
106
97
|
|
107
|
-
<script
|
98
|
+
<script>
|
108
99
|
// support forEach iterator on NodeList
|
109
100
|
NodeList.prototype.forEach = Array.prototype.forEach;
|
110
101
|
|
@@ -24,6 +24,8 @@ module ActionDispatch
|
|
24
24
|
config.action_dispatch.use_cookies_with_metadata = false
|
25
25
|
config.action_dispatch.perform_deep_munge = true
|
26
26
|
config.action_dispatch.request_id_header = "X-Request-Id"
|
27
|
+
config.action_dispatch.return_only_request_media_type_on_content_type = true
|
28
|
+
config.action_dispatch.log_rescued_responses = true
|
27
29
|
|
28
30
|
config.action_dispatch.default_headers = {
|
29
31
|
"X-Frame-Options" => "SAMEORIGIN",
|
@@ -41,8 +43,12 @@ module ActionDispatch
|
|
41
43
|
initializer "action_dispatch.configure" do |app|
|
42
44
|
ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
|
43
45
|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
|
44
|
-
|
45
|
-
|
46
|
+
|
47
|
+
ActiveSupport.on_load(:action_dispatch_request) do
|
48
|
+
self.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
|
49
|
+
self.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_request_media_type_on_content_type
|
50
|
+
ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
|
51
|
+
end
|
46
52
|
|
47
53
|
ActiveSupport.on_load(:action_dispatch_response) do
|
48
54
|
self.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
|
@@ -6,6 +6,7 @@ module ActionDispatch
|
|
6
6
|
class Request
|
7
7
|
# Session is responsible for lazily loading the session from store.
|
8
8
|
class Session # :nodoc:
|
9
|
+
DisabledSessionError = Class.new(StandardError)
|
9
10
|
ENV_SESSION_KEY = Rack::RACK_SESSION # :nodoc:
|
10
11
|
ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS # :nodoc:
|
11
12
|
|
@@ -23,6 +24,12 @@ module ActionDispatch
|
|
23
24
|
session
|
24
25
|
end
|
25
26
|
|
27
|
+
def self.disabled(req)
|
28
|
+
new(nil, req, enabled: false).tap do
|
29
|
+
Session::Options.set(req, Session::Options.new(nil, { id: nil }))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
26
33
|
def self.find(req)
|
27
34
|
req.get_header ENV_SESSION_KEY
|
28
35
|
end
|
@@ -31,7 +38,11 @@ module ActionDispatch
|
|
31
38
|
req.set_header ENV_SESSION_KEY, session
|
32
39
|
end
|
33
40
|
|
34
|
-
|
41
|
+
def self.delete(req)
|
42
|
+
req.delete_header ENV_SESSION_KEY
|
43
|
+
end
|
44
|
+
|
45
|
+
class Options # :nodoc:
|
35
46
|
def self.set(req, options)
|
36
47
|
req.set_header ENV_SESSION_OPTIONS_KEY, options
|
37
48
|
end
|
@@ -60,30 +71,38 @@ module ActionDispatch
|
|
60
71
|
def values_at(*args); @delegate.values_at(*args); end
|
61
72
|
end
|
62
73
|
|
63
|
-
def initialize(by, req)
|
74
|
+
def initialize(by, req, enabled: true)
|
64
75
|
@by = by
|
65
76
|
@req = req
|
66
77
|
@delegate = {}
|
67
78
|
@loaded = false
|
68
79
|
@exists = nil # We haven't checked yet.
|
80
|
+
@enabled = enabled
|
69
81
|
end
|
70
82
|
|
71
83
|
def id
|
72
84
|
options.id(@req)
|
73
85
|
end
|
74
86
|
|
87
|
+
def enabled?
|
88
|
+
@enabled
|
89
|
+
end
|
90
|
+
|
75
91
|
def options
|
76
92
|
Options.find @req
|
77
93
|
end
|
78
94
|
|
79
95
|
def destroy
|
80
96
|
clear
|
81
|
-
options = self.options || {}
|
82
|
-
@by.send(:delete_session, @req, options.id(@req), options)
|
83
97
|
|
84
|
-
|
85
|
-
|
86
|
-
|
98
|
+
if enabled?
|
99
|
+
options = self.options || {}
|
100
|
+
@by.send(:delete_session, @req, options.id(@req), options)
|
101
|
+
|
102
|
+
# Load the new sid to be written with the response.
|
103
|
+
@loaded = false
|
104
|
+
load_for_write!
|
105
|
+
end
|
87
106
|
end
|
88
107
|
|
89
108
|
# Returns value of the key stored in the session or
|
@@ -135,7 +154,7 @@ module ActionDispatch
|
|
135
154
|
|
136
155
|
# Clears the session.
|
137
156
|
def clear
|
138
|
-
|
157
|
+
load_for_delete!
|
139
158
|
@delegate.clear
|
140
159
|
end
|
141
160
|
|
@@ -163,7 +182,7 @@ module ActionDispatch
|
|
163
182
|
|
164
183
|
# Deletes given key from the session.
|
165
184
|
def delete(key)
|
166
|
-
|
185
|
+
load_for_delete!
|
167
186
|
@delegate.delete key.to_s
|
168
187
|
end
|
169
188
|
|
@@ -199,6 +218,7 @@ module ActionDispatch
|
|
199
218
|
end
|
200
219
|
|
201
220
|
def exists?
|
221
|
+
return false unless enabled?
|
202
222
|
return @exists unless @exists.nil?
|
203
223
|
@exists = @by.send(:session_exists?, @req)
|
204
224
|
end
|
@@ -227,13 +247,23 @@ module ActionDispatch
|
|
227
247
|
end
|
228
248
|
|
229
249
|
def load_for_write!
|
230
|
-
|
250
|
+
if enabled?
|
251
|
+
load! unless loaded?
|
252
|
+
else
|
253
|
+
raise DisabledSessionError, "Your application has sessions disabled. To write to the session you must first configure a session store"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def load_for_delete!
|
258
|
+
load! if enabled? && !loaded?
|
231
259
|
end
|
232
260
|
|
233
261
|
def load!
|
234
|
-
|
235
|
-
|
236
|
-
|
262
|
+
if enabled?
|
263
|
+
id, session = @by.load_session @req
|
264
|
+
options[:id] = id
|
265
|
+
@delegate.replace(session.stringify_keys)
|
266
|
+
end
|
237
267
|
@loaded = true
|
238
268
|
end
|
239
269
|
end
|
@@ -4,7 +4,6 @@ require "active_support/core_ext/hash/slice"
|
|
4
4
|
require "active_support/core_ext/enumerable"
|
5
5
|
require "active_support/core_ext/array/extract_options"
|
6
6
|
require "active_support/core_ext/regexp"
|
7
|
-
require "active_support/core_ext/symbol/starts_ends_with"
|
8
7
|
require "action_dispatch/routing/redirection"
|
9
8
|
require "action_dispatch/routing/endpoint"
|
10
9
|
|
@@ -13,7 +12,7 @@ module ActionDispatch
|
|
13
12
|
class Mapper
|
14
13
|
URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port]
|
15
14
|
|
16
|
-
class Constraints < Routing::Endpoint
|
15
|
+
class Constraints < Routing::Endpoint # :nodoc:
|
17
16
|
attr_reader :app, :constraints
|
18
17
|
|
19
18
|
SERVE = ->(app, req) { app.serve req }
|
@@ -67,11 +66,11 @@ module ActionDispatch
|
|
67
66
|
end
|
68
67
|
end
|
69
68
|
|
70
|
-
class Mapping
|
69
|
+
class Mapping # :nodoc:
|
71
70
|
ANCHOR_CHARACTERS_REGEX = %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
|
72
71
|
OPTIONAL_FORMAT_REGEX = %r{(?:\(\.:format\)+|\.:format|/)\Z}
|
73
72
|
|
74
|
-
attr_reader :requirements, :defaults, :to, :default_controller,
|
73
|
+
attr_reader :path, :requirements, :defaults, :to, :default_controller,
|
75
74
|
:default_action, :required_defaults, :ast, :scope_options
|
76
75
|
|
77
76
|
def self.build(scope, set, ast, controller, default_action, to, via, formatted, options_constraints, anchor, options)
|
@@ -122,31 +121,17 @@ module ActionDispatch
|
|
122
121
|
@to = intern(to)
|
123
122
|
@default_controller = intern(controller)
|
124
123
|
@default_action = intern(default_action)
|
125
|
-
@ast = ast
|
126
124
|
@anchor = anchor
|
127
125
|
@via = via
|
128
126
|
@internal = options.delete(:internal)
|
129
127
|
@scope_options = scope_params[:options]
|
128
|
+
ast = Journey::Ast.new(ast, formatted)
|
130
129
|
|
131
|
-
|
132
|
-
wildcard_options = {}
|
133
|
-
ast.each do |node|
|
134
|
-
if node.symbol?
|
135
|
-
path_params << node.to_sym
|
136
|
-
elsif formatted != false && node.star?
|
137
|
-
# Add a constraint for wildcard route to make it non-greedy and match the
|
138
|
-
# optional format part of the route by default.
|
139
|
-
wildcard_options[node.name.to_sym] ||= /.+?/
|
140
|
-
elsif node.cat?
|
141
|
-
alter_regex_for_custom_routes(node)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
options = wildcard_options.merge!(options)
|
130
|
+
options = ast.wildcard_options.merge!(options)
|
146
131
|
|
147
|
-
options = normalize_options!(options, path_params, scope_params[:module])
|
132
|
+
options = normalize_options!(options, ast.path_params, scope_params[:module])
|
148
133
|
|
149
|
-
split_options = constraints(options, path_params)
|
134
|
+
split_options = constraints(options, ast.path_params)
|
150
135
|
|
151
136
|
constraints = scope_params[:constraints].merge Hash[split_options[:constraints] || []]
|
152
137
|
|
@@ -160,7 +145,7 @@ module ActionDispatch
|
|
160
145
|
@blocks = blocks(options_constraints)
|
161
146
|
end
|
162
147
|
|
163
|
-
requirements, conditions = split_constraints path_params, constraints
|
148
|
+
requirements, conditions = split_constraints ast.path_params, constraints
|
164
149
|
verify_regexp_requirements requirements.map(&:last).grep(Regexp)
|
165
150
|
|
166
151
|
formats = normalize_format(formatted)
|
@@ -169,13 +154,18 @@ module ActionDispatch
|
|
169
154
|
@conditions = Hash[conditions]
|
170
155
|
@defaults = formats[:defaults].merge(@defaults).merge(normalize_defaults(options))
|
171
156
|
|
172
|
-
if path_params.include?(:action) && !@requirements.key?(:action)
|
157
|
+
if ast.path_params.include?(:action) && !@requirements.key?(:action)
|
173
158
|
@defaults[:action] ||= "index"
|
174
159
|
end
|
175
160
|
|
176
161
|
@required_defaults = (split_options[:required_defaults] || []).map(&:first)
|
162
|
+
|
163
|
+
ast.requirements = @requirements
|
164
|
+
@path = Journey::Path::Pattern.new(ast, @requirements, JOINED_SEPARATORS, @anchor)
|
177
165
|
end
|
178
166
|
|
167
|
+
JOINED_SEPARATORS = SEPARATORS.join # :nodoc:
|
168
|
+
|
179
169
|
def make_route(name, precedence)
|
180
170
|
Journey::Route.new(name: name, app: application, path: path, constraints: conditions,
|
181
171
|
required_defaults: required_defaults, defaults: defaults,
|
@@ -187,12 +177,6 @@ module ActionDispatch
|
|
187
177
|
app(@blocks)
|
188
178
|
end
|
189
179
|
|
190
|
-
JOINED_SEPARATORS = SEPARATORS.join # :nodoc:
|
191
|
-
|
192
|
-
def path
|
193
|
-
Journey::Path::Pattern.new(@ast, requirements, JOINED_SEPARATORS, @anchor)
|
194
|
-
end
|
195
|
-
|
196
180
|
def conditions
|
197
181
|
build_conditions @conditions, @set.request_class
|
198
182
|
end
|
@@ -212,24 +196,6 @@ module ActionDispatch
|
|
212
196
|
private :request_method
|
213
197
|
|
214
198
|
private
|
215
|
-
# Find all the symbol nodes that are adjacent to literal nodes and alter
|
216
|
-
# the regexp so that Journey will partition them into custom routes.
|
217
|
-
def alter_regex_for_custom_routes(node)
|
218
|
-
if node.left.literal? && node.right.symbol?
|
219
|
-
symbol = node.right
|
220
|
-
elsif node.left.literal? && node.right.cat? && node.right.left.symbol?
|
221
|
-
symbol = node.right.left
|
222
|
-
elsif node.left.symbol? && node.right.literal?
|
223
|
-
symbol = node.left
|
224
|
-
elsif node.left.symbol? && node.right.cat? && node.right.left.literal?
|
225
|
-
symbol = node.left
|
226
|
-
end
|
227
|
-
|
228
|
-
if symbol
|
229
|
-
symbol.regexp = /(?:#{Regexp.union(symbol.regexp, '-')})+/
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
199
|
def intern(object)
|
234
200
|
object.is_a?(String) ? -object : object
|
235
201
|
end
|
@@ -956,7 +922,7 @@ module ActionDispatch
|
|
956
922
|
# namespace :admin, as: "sekret" do
|
957
923
|
# resources :posts
|
958
924
|
# end
|
959
|
-
def namespace(path, options = {})
|
925
|
+
def namespace(path, options = {}, &block)
|
960
926
|
path = path.to_s
|
961
927
|
|
962
928
|
defaults = {
|
@@ -967,7 +933,7 @@ module ActionDispatch
|
|
967
933
|
}
|
968
934
|
|
969
935
|
path_scope(options.delete(:path) { path }) do
|
970
|
-
scope(defaults.merge!(options))
|
936
|
+
scope(defaults.merge!(options), &block)
|
971
937
|
end
|
972
938
|
end
|
973
939
|
|
@@ -1026,8 +992,8 @@ module ActionDispatch
|
|
1026
992
|
# constraints(Iphone) do
|
1027
993
|
# resources :iphones
|
1028
994
|
# end
|
1029
|
-
def constraints(constraints = {})
|
1030
|
-
scope(constraints: constraints)
|
995
|
+
def constraints(constraints = {}, &block)
|
996
|
+
scope(constraints: constraints, &block)
|
1031
997
|
end
|
1032
998
|
|
1033
999
|
# Allows you to set default parameters for a route, such as this:
|
@@ -1156,7 +1122,7 @@ module ActionDispatch
|
|
1156
1122
|
RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param, :concerns]
|
1157
1123
|
CANONICAL_ACTIONS = %w(index create new show update destroy)
|
1158
1124
|
|
1159
|
-
class Resource
|
1125
|
+
class Resource # :nodoc:
|
1160
1126
|
attr_reader :controller, :path, :param
|
1161
1127
|
|
1162
1128
|
def initialize(entities, api_only, shallow, options = {})
|
@@ -1251,7 +1217,7 @@ module ActionDispatch
|
|
1251
1217
|
def singleton?; false; end
|
1252
1218
|
end
|
1253
1219
|
|
1254
|
-
class SingletonResource < Resource
|
1220
|
+
class SingletonResource < Resource # :nodoc:
|
1255
1221
|
def initialize(entities, api_only, shallow, options)
|
1256
1222
|
super
|
1257
1223
|
@as = nil
|
@@ -1307,6 +1273,16 @@ module ActionDispatch
|
|
1307
1273
|
# DELETE /profile
|
1308
1274
|
# POST /profile
|
1309
1275
|
#
|
1276
|
+
# If you want instances of a model to work with this resource via
|
1277
|
+
# record identification (e.g. in +form_with+ or +redirect_to+), you
|
1278
|
+
# will need to call resolve[rdoc-ref:CustomUrls#resolve]:
|
1279
|
+
#
|
1280
|
+
# resource :profile
|
1281
|
+
# resolve('Profile') { [:profile] }
|
1282
|
+
#
|
1283
|
+
# # Enables this to work with singular routes:
|
1284
|
+
# form_with(model: @profile) {}
|
1285
|
+
#
|
1310
1286
|
# === Options
|
1311
1287
|
# Takes same options as resources[rdoc-ref:#resources]
|
1312
1288
|
def resource(*resources, &block)
|
@@ -1517,15 +1493,13 @@ module ActionDispatch
|
|
1517
1493
|
# with GET, and route to the search action of +PhotosController+. It will also
|
1518
1494
|
# create the <tt>search_photos_url</tt> and <tt>search_photos_path</tt>
|
1519
1495
|
# route helpers.
|
1520
|
-
def collection
|
1496
|
+
def collection(&block)
|
1521
1497
|
unless resource_scope?
|
1522
1498
|
raise ArgumentError, "can't use collection outside resource(s) scope"
|
1523
1499
|
end
|
1524
1500
|
|
1525
1501
|
with_scope_level(:collection) do
|
1526
|
-
path_scope(parent_resource.collection_scope)
|
1527
|
-
yield
|
1528
|
-
end
|
1502
|
+
path_scope(parent_resource.collection_scope, &block)
|
1529
1503
|
end
|
1530
1504
|
end
|
1531
1505
|
|
@@ -1540,7 +1514,7 @@ module ActionDispatch
|
|
1540
1514
|
# This will recognize <tt>/photos/1/preview</tt> with GET, and route to the
|
1541
1515
|
# preview action of +PhotosController+. It will also create the
|
1542
1516
|
# <tt>preview_photo_url</tt> and <tt>preview_photo_path</tt> helpers.
|
1543
|
-
def member
|
1517
|
+
def member(&block)
|
1544
1518
|
unless resource_scope?
|
1545
1519
|
raise ArgumentError, "can't use member outside resource(s) scope"
|
1546
1520
|
end
|
@@ -1548,27 +1522,25 @@ module ActionDispatch
|
|
1548
1522
|
with_scope_level(:member) do
|
1549
1523
|
if shallow?
|
1550
1524
|
shallow_scope {
|
1551
|
-
path_scope(parent_resource.member_scope)
|
1525
|
+
path_scope(parent_resource.member_scope, &block)
|
1552
1526
|
}
|
1553
1527
|
else
|
1554
|
-
path_scope(parent_resource.member_scope)
|
1528
|
+
path_scope(parent_resource.member_scope, &block)
|
1555
1529
|
end
|
1556
1530
|
end
|
1557
1531
|
end
|
1558
1532
|
|
1559
|
-
def new
|
1533
|
+
def new(&block)
|
1560
1534
|
unless resource_scope?
|
1561
1535
|
raise ArgumentError, "can't use new outside resource(s) scope"
|
1562
1536
|
end
|
1563
1537
|
|
1564
1538
|
with_scope_level(:new) do
|
1565
|
-
path_scope(parent_resource.new_scope(action_path(:new)))
|
1566
|
-
yield
|
1567
|
-
end
|
1539
|
+
path_scope(parent_resource.new_scope(action_path(:new)), &block)
|
1568
1540
|
end
|
1569
1541
|
end
|
1570
1542
|
|
1571
|
-
def nested
|
1543
|
+
def nested(&block)
|
1572
1544
|
unless resource_scope?
|
1573
1545
|
raise ArgumentError, "can't use nested outside resource(s) scope"
|
1574
1546
|
end
|
@@ -1577,12 +1549,12 @@ module ActionDispatch
|
|
1577
1549
|
if shallow? && shallow_nesting_depth >= 1
|
1578
1550
|
shallow_scope do
|
1579
1551
|
path_scope(parent_resource.nested_scope) do
|
1580
|
-
scope(nested_options)
|
1552
|
+
scope(nested_options, &block)
|
1581
1553
|
end
|
1582
1554
|
end
|
1583
1555
|
else
|
1584
1556
|
path_scope(parent_resource.nested_scope) do
|
1585
|
-
scope(nested_options)
|
1557
|
+
scope(nested_options, &block)
|
1586
1558
|
end
|
1587
1559
|
end
|
1588
1560
|
end
|
@@ -1768,10 +1740,10 @@ module ActionDispatch
|
|
1768
1740
|
@scope = @scope.parent
|
1769
1741
|
end
|
1770
1742
|
|
1771
|
-
def resource_scope(resource)
|
1743
|
+
def resource_scope(resource, &block)
|
1772
1744
|
@scope = @scope.new(scope_level_resource: resource)
|
1773
1745
|
|
1774
|
-
controller(resource.resource_scope)
|
1746
|
+
controller(resource.resource_scope, &block)
|
1775
1747
|
ensure
|
1776
1748
|
@scope = @scope.parent
|
1777
1749
|
end
|
@@ -1889,7 +1861,7 @@ module ActionDispatch
|
|
1889
1861
|
end
|
1890
1862
|
|
1891
1863
|
def map_match(paths, options)
|
1892
|
-
if options[:on] && !VALID_ON_OPTIONS.include?(
|
1864
|
+
if (on = options[:on]) && !VALID_ON_OPTIONS.include?(on)
|
1893
1865
|
raise ArgumentError, "Unknown scope #{on.inspect} given to :on"
|
1894
1866
|
end
|
1895
1867
|
|
@@ -2300,7 +2272,7 @@ module ActionDispatch
|
|
2300
2272
|
NULL = Scope.new(nil, nil)
|
2301
2273
|
end
|
2302
2274
|
|
2303
|
-
def initialize(set)
|
2275
|
+
def initialize(set) # :nodoc:
|
2304
2276
|
@set = set
|
2305
2277
|
@draw_paths = set.draw_paths
|
2306
2278
|
@scope = Scope.new(path_names: @set.resources_path_names)
|