actionpack 4.2.10 → 6.1.4
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 +5 -5
- data/CHANGELOG.md +311 -461
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -9
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +81 -51
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +61 -33
- data/lib/abstract_controller/collector.rb +9 -13
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +115 -99
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
- data/lib/abstract_controller/rendering.rb +48 -47
- data/lib/abstract_controller/translation.rb +17 -8
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +13 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +150 -0
- data/lib/action_controller/base.rb +29 -24
- data/lib/action_controller/caching.rb +12 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +17 -19
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +134 -46
- data/lib/action_controller/metal/content_security_policy.rb +51 -0
- data/lib/action_controller/metal/cookies.rb +6 -4
- data/lib/action_controller/metal/data_streaming.rb +30 -50
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
- data/lib/action_controller/metal/exceptions.rb +63 -15
- data/lib/action_controller/metal/flash.rb +9 -8
- data/lib/action_controller/metal/head.rb +26 -21
- data/lib/action_controller/metal/helpers.rb +37 -18
- data/lib/action_controller/metal/http_authentication.rb +81 -73
- data/lib/action_controller/metal/implicit_render.rb +53 -9
- data/lib/action_controller/metal/instrumentation.rb +32 -35
- data/lib/action_controller/metal/live.rb +110 -119
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +49 -47
- data/lib/action_controller/metal/parameter_encoding.rb +82 -0
- data/lib/action_controller/metal/params_wrapper.rb +84 -66
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +53 -32
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +77 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
- data/lib/action_controller/metal/rescue.rb +10 -17
- data/lib/action_controller/metal/streaming.rb +12 -11
- data/lib/action_controller/metal/strong_parameters.rb +714 -186
- data/lib/action_controller/metal/testing.rb +2 -17
- data/lib/action_controller/metal/url_for.rb +19 -10
- data/lib/action_controller/metal.rb +104 -87
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +3 -1
- data/lib/action_controller/renderer.rb +141 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +298 -421
- data/lib/action_controller.rb +34 -23
- data/lib/action_dispatch/http/cache.rb +108 -58
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +286 -0
- data/lib/action_dispatch/http/filter_parameters.rb +32 -25
- data/lib/action_dispatch/http/filter_redirect.rb +10 -12
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +82 -50
- data/lib/action_dispatch/http/mime_type.rb +153 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameters.rb +90 -40
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +226 -121
- data/lib/action_dispatch/http/response.rb +248 -113
- data/lib/action_dispatch/http/upload.rb +21 -7
- data/lib/action_dispatch/http/url.rb +182 -100
- data/lib/action_dispatch/journey/formatter.rb +91 -44
- data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
- data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
- data/lib/action_dispatch/journey/nodes/node.rb +29 -15
- data/lib/action_dispatch/journey/parser.rb +17 -16
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +58 -54
- data/lib/action_dispatch/journey/route.rb +100 -32
- data/lib/action_dispatch/journey/router/utils.rb +29 -18
- data/lib/action_dispatch/journey/router.rb +55 -51
- data/lib/action_dispatch/journey/routes.rb +17 -17
- data/lib/action_dispatch/journey/scanner.rb +26 -17
- data/lib/action_dispatch/journey/visitors.rb +98 -54
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +3 -6
- data/lib/action_dispatch/middleware/cookies.rb +347 -217
- data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
- data/lib/action_dispatch/middleware/request_id.rb +17 -10
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
- data/lib/action_dispatch/middleware/ssl.rb +118 -35
- data/lib/action_dispatch/middleware/stack.rb +82 -41
- data/lib/action_dispatch/middleware/static.rb +156 -89
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
- data/lib/action_dispatch/railtie.rb +27 -13
- data/lib/action_dispatch/request/session.rb +109 -61
- data/lib/action_dispatch/request/utils.rb +90 -23
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +141 -102
- data/lib/action_dispatch/routing/mapper.rb +811 -473
- data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
- data/lib/action_dispatch/routing/redirection.rb +37 -27
- data/lib/action_dispatch/routing/route_set.rb +363 -331
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +66 -26
- data/lib/action_dispatch/routing.rb +36 -36
- data/lib/action_dispatch/system_test_case.rb +190 -0
- data/lib/action_dispatch/system_testing/browser.rb +86 -0
- data/lib/action_dispatch/system_testing/driver.rb +67 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
- data/lib/action_dispatch/testing/assertion_response.rb +46 -0
- data/lib/action_dispatch/testing/assertions/response.rb +44 -22
- data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +391 -220
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +53 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +11 -11
- data/lib/action_dispatch.rb +35 -21
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +75 -46
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Routing
|
@@ -6,7 +6,7 @@ module ActionDispatch
|
|
6
6
|
# given an Active Record model instance. They are to be used in combination with
|
7
7
|
# ActionController::Resources.
|
8
8
|
#
|
9
|
-
# These methods are useful when you want to generate correct URL or path to a RESTful
|
9
|
+
# These methods are useful when you want to generate the correct URL or path to a RESTful
|
10
10
|
# resource without having to know the exact type of the record in question.
|
11
11
|
#
|
12
12
|
# Nested resources and/or namespaces are also supported, as illustrated in the example:
|
@@ -42,7 +42,7 @@ module ActionDispatch
|
|
42
42
|
#
|
43
43
|
# Example usage:
|
44
44
|
#
|
45
|
-
# edit_polymorphic_path(@post)
|
45
|
+
# edit_polymorphic_path(@post) # => "/posts/1/edit"
|
46
46
|
# polymorphic_path(@post, format: :pdf) # => "/posts/1.pdf"
|
47
47
|
#
|
48
48
|
# == Usage with mounted engines
|
@@ -55,8 +55,6 @@ module ActionDispatch
|
|
55
55
|
# form_for([blog, @post]) # => "/blog/posts/1"
|
56
56
|
#
|
57
57
|
module PolymorphicRoutes
|
58
|
-
include ActionController::ModelNaming
|
59
|
-
|
60
58
|
# Constructs a call to a named RESTful route for the given record and returns the
|
61
59
|
# resulting URL string. For example:
|
62
60
|
#
|
@@ -83,7 +81,7 @@ module ActionDispatch
|
|
83
81
|
# polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
|
84
82
|
# # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
|
85
83
|
#
|
86
|
-
# For all of these options, see the documentation for
|
84
|
+
# For all of these options, see the documentation for {url_for}[rdoc-ref:ActionDispatch::Routing::UrlFor].
|
87
85
|
#
|
88
86
|
# ==== Functionality
|
89
87
|
#
|
@@ -107,6 +105,10 @@ module ActionDispatch
|
|
107
105
|
return polymorphic_url record, options
|
108
106
|
end
|
109
107
|
|
108
|
+
if mapping = polymorphic_mapping(record_or_hash_or_array)
|
109
|
+
return mapping.call(self, [record_or_hash_or_array, options], false)
|
110
|
+
end
|
111
|
+
|
110
112
|
opts = options.dup
|
111
113
|
action = opts.delete :action
|
112
114
|
type = opts.delete(:routing_type) || :url
|
@@ -118,8 +120,7 @@ module ActionDispatch
|
|
118
120
|
opts
|
119
121
|
end
|
120
122
|
|
121
|
-
# Returns the path component of a URL for the given record.
|
122
|
-
# <tt>polymorphic_url</tt> with <tt>routing_type: :path</tt>.
|
123
|
+
# Returns the path component of a URL for the given record.
|
123
124
|
def polymorphic_path(record_or_hash_or_array, options = {})
|
124
125
|
if Hash === record_or_hash_or_array
|
125
126
|
options = record_or_hash_or_array.merge(options)
|
@@ -127,6 +128,10 @@ module ActionDispatch
|
|
127
128
|
return polymorphic_path record, options
|
128
129
|
end
|
129
130
|
|
131
|
+
if mapping = polymorphic_mapping(record_or_hash_or_array)
|
132
|
+
return mapping.call(self, [record_or_hash_or_array, options], true)
|
133
|
+
end
|
134
|
+
|
130
135
|
opts = options.dup
|
131
136
|
action = opts.delete :action
|
132
137
|
type = :path
|
@@ -138,9 +143,9 @@ module ActionDispatch
|
|
138
143
|
opts
|
139
144
|
end
|
140
145
|
|
141
|
-
|
142
146
|
%w(edit new).each do |action|
|
143
147
|
module_eval <<-EOT, __FILE__, __LINE__ + 1
|
148
|
+
# frozen_string_literal: true
|
144
149
|
def #{action}_polymorphic_url(record_or_hash, options = {})
|
145
150
|
polymorphic_url_for_action("#{action}", record_or_hash, options)
|
146
151
|
end
|
@@ -152,179 +157,198 @@ module ActionDispatch
|
|
152
157
|
end
|
153
158
|
|
154
159
|
private
|
155
|
-
|
156
|
-
|
157
|
-
polymorphic_url(record_or_hash, options.merge(:action => action))
|
158
|
-
end
|
159
|
-
|
160
|
-
def polymorphic_path_for_action(action, record_or_hash, options)
|
161
|
-
polymorphic_path(record_or_hash, options.merge(:action => action))
|
162
|
-
end
|
163
|
-
|
164
|
-
class HelperMethodBuilder # :nodoc:
|
165
|
-
CACHE = { 'path' => {}, 'url' => {} }
|
166
|
-
|
167
|
-
def self.get(action, type)
|
168
|
-
type = type.to_s
|
169
|
-
CACHE[type].fetch(action) { build action, type }
|
160
|
+
def polymorphic_url_for_action(action, record_or_hash, options)
|
161
|
+
polymorphic_url(record_or_hash, options.merge(action: action))
|
170
162
|
end
|
171
163
|
|
172
|
-
def
|
173
|
-
|
164
|
+
def polymorphic_path_for_action(action, record_or_hash, options)
|
165
|
+
polymorphic_path(record_or_hash, options.merge(action: action))
|
166
|
+
end
|
174
167
|
|
175
|
-
def
|
176
|
-
|
177
|
-
|
178
|
-
if action.to_s == 'new'
|
179
|
-
HelperMethodBuilder.singular prefix, suffix
|
168
|
+
def polymorphic_mapping(record)
|
169
|
+
if record.respond_to?(:to_model)
|
170
|
+
_routes.polymorphic_mappings[record.to_model.model_name.name]
|
180
171
|
else
|
181
|
-
|
172
|
+
_routes.polymorphic_mappings[record.class.name]
|
182
173
|
end
|
183
174
|
end
|
184
175
|
|
185
|
-
|
186
|
-
|
187
|
-
end
|
176
|
+
class HelperMethodBuilder # :nodoc:
|
177
|
+
CACHE = { path: {}, url: {} }
|
188
178
|
|
189
|
-
|
190
|
-
|
191
|
-
|
179
|
+
def self.get(action, type)
|
180
|
+
type = type.to_sym
|
181
|
+
CACHE[type].fetch(action) { build action, type }
|
182
|
+
end
|
192
183
|
|
193
|
-
|
194
|
-
|
184
|
+
def self.url; CACHE[:url][nil]; end
|
185
|
+
def self.path; CACHE[:path][nil]; end
|
195
186
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
if
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
recipient = record_or_hash_or_array.shift
|
187
|
+
def self.build(action, type)
|
188
|
+
prefix = action ? "#{action}_" : ""
|
189
|
+
suffix = type
|
190
|
+
if action.to_s == "new"
|
191
|
+
HelperMethodBuilder.singular prefix, suffix
|
192
|
+
else
|
193
|
+
HelperMethodBuilder.plural prefix, suffix
|
204
194
|
end
|
205
|
-
|
206
|
-
method, args = builder.handle_list record_or_hash_or_array
|
207
|
-
when String, Symbol
|
208
|
-
method, args = builder.handle_string record_or_hash_or_array
|
209
|
-
when Class
|
210
|
-
method, args = builder.handle_class record_or_hash_or_array
|
211
|
-
|
212
|
-
when nil
|
213
|
-
raise ArgumentError, "Nil location provided. Can't build URI."
|
214
|
-
else
|
215
|
-
method, args = builder.handle_model record_or_hash_or_array
|
216
195
|
end
|
217
196
|
|
218
|
-
|
219
|
-
|
220
|
-
recipient.send(method, *args)
|
221
|
-
else
|
222
|
-
recipient.send(method, *args, options)
|
197
|
+
def self.singular(prefix, suffix)
|
198
|
+
new(->(name) { name.singular_route_key }, prefix, suffix)
|
223
199
|
end
|
224
|
-
end
|
225
200
|
|
226
|
-
|
201
|
+
def self.plural(prefix, suffix)
|
202
|
+
new(->(name) { name.route_key }, prefix, suffix)
|
203
|
+
end
|
227
204
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
205
|
+
def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
|
206
|
+
builder = get action, type
|
207
|
+
|
208
|
+
case record_or_hash_or_array
|
209
|
+
when Array
|
210
|
+
record_or_hash_or_array = record_or_hash_or_array.compact
|
211
|
+
if record_or_hash_or_array.empty?
|
212
|
+
raise ArgumentError, "Nil location provided. Can't build URI."
|
213
|
+
end
|
214
|
+
if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
|
215
|
+
recipient = record_or_hash_or_array.shift
|
216
|
+
end
|
217
|
+
|
218
|
+
method, args = builder.handle_list record_or_hash_or_array
|
219
|
+
when String, Symbol
|
220
|
+
method, args = builder.handle_string record_or_hash_or_array
|
221
|
+
when Class
|
222
|
+
method, args = builder.handle_class record_or_hash_or_array
|
233
223
|
|
234
|
-
|
235
|
-
|
236
|
-
|
224
|
+
when nil
|
225
|
+
raise ArgumentError, "Nil location provided. Can't build URI."
|
226
|
+
else
|
227
|
+
method, args = builder.handle_model record_or_hash_or_array
|
228
|
+
end
|
237
229
|
|
238
|
-
|
239
|
-
|
240
|
-
|
230
|
+
if options.empty?
|
231
|
+
recipient.public_send(method, *args)
|
232
|
+
else
|
233
|
+
recipient.public_send(method, *args, options)
|
234
|
+
end
|
235
|
+
end
|
241
236
|
|
242
|
-
|
243
|
-
[get_method_for_class(klass), []]
|
244
|
-
end
|
237
|
+
attr_reader :suffix, :prefix
|
245
238
|
|
246
|
-
|
247
|
-
|
248
|
-
|
239
|
+
def initialize(key_strategy, prefix, suffix)
|
240
|
+
@key_strategy = key_strategy
|
241
|
+
@prefix = prefix
|
242
|
+
@suffix = suffix
|
243
|
+
end
|
249
244
|
|
250
|
-
|
251
|
-
|
245
|
+
def handle_string(record)
|
246
|
+
[get_method_for_string(record), []]
|
247
|
+
end
|
252
248
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
model.model_name.singular_route_key
|
257
|
-
else
|
258
|
-
@key_strategy.call model.model_name
|
259
|
-
end
|
249
|
+
def handle_string_call(target, str)
|
250
|
+
target.public_send get_method_for_string str
|
251
|
+
end
|
260
252
|
|
261
|
-
|
253
|
+
def handle_class(klass)
|
254
|
+
[get_method_for_class(klass), []]
|
255
|
+
end
|
262
256
|
|
263
|
-
|
264
|
-
|
257
|
+
def handle_class_call(target, klass)
|
258
|
+
target.public_send get_method_for_class klass
|
259
|
+
end
|
265
260
|
|
266
|
-
|
267
|
-
|
268
|
-
target.send(method, *args)
|
269
|
-
end
|
261
|
+
def handle_model(record)
|
262
|
+
args = []
|
270
263
|
|
271
|
-
|
272
|
-
|
273
|
-
|
264
|
+
model = record.to_model
|
265
|
+
named_route = if model.persisted?
|
266
|
+
args << model
|
267
|
+
get_method_for_string model.model_name.singular_route_key
|
268
|
+
else
|
269
|
+
get_method_for_class model
|
270
|
+
end
|
274
271
|
|
275
|
-
|
272
|
+
[named_route, args]
|
273
|
+
end
|
276
274
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
parent.to_s
|
281
|
-
when Class
|
282
|
-
args << parent
|
283
|
-
parent.model_name.singular_route_key
|
275
|
+
def handle_model_call(target, record)
|
276
|
+
if mapping = polymorphic_mapping(target, record)
|
277
|
+
mapping.call(target, [record], suffix == "path")
|
284
278
|
else
|
285
|
-
args
|
286
|
-
|
279
|
+
method, args = handle_model(record)
|
280
|
+
target.public_send(method, *args)
|
287
281
|
end
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
282
|
+
end
|
283
|
+
|
284
|
+
def handle_list(list)
|
285
|
+
record_list = list.dup
|
286
|
+
record = record_list.pop
|
287
|
+
|
288
|
+
args = []
|
289
|
+
|
290
|
+
route = record_list.map do |parent|
|
291
|
+
case parent
|
292
|
+
when Symbol
|
293
|
+
parent.to_s
|
294
|
+
when String
|
295
|
+
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
|
296
|
+
when Class
|
297
|
+
args << parent
|
298
|
+
parent.model_name.singular_route_key
|
299
|
+
else
|
300
|
+
args << parent.to_model
|
301
|
+
parent.to_model.model_name.singular_route_key
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
route <<
|
306
|
+
case record
|
307
|
+
when Symbol
|
308
|
+
record.to_s
|
309
|
+
when String
|
310
|
+
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
|
311
|
+
when Class
|
312
|
+
@key_strategy.call record.model_name
|
301
313
|
else
|
302
|
-
|
314
|
+
model = record.to_model
|
315
|
+
if model.persisted?
|
316
|
+
args << model
|
317
|
+
model.model_name.singular_route_key
|
318
|
+
else
|
319
|
+
@key_strategy.call model.model_name
|
320
|
+
end
|
303
321
|
end
|
304
|
-
end
|
305
322
|
|
306
|
-
|
323
|
+
route << suffix
|
307
324
|
|
308
|
-
|
309
|
-
|
310
|
-
|
325
|
+
named_route = prefix + route.join("_")
|
326
|
+
[named_route, args]
|
327
|
+
end
|
311
328
|
|
312
|
-
|
329
|
+
private
|
330
|
+
def polymorphic_mapping(target, record)
|
331
|
+
if record.respond_to?(:to_model)
|
332
|
+
target._routes.polymorphic_mappings[record.to_model.model_name.name]
|
333
|
+
else
|
334
|
+
target._routes.polymorphic_mappings[record.class.name]
|
335
|
+
end
|
336
|
+
end
|
313
337
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
338
|
+
def get_method_for_class(klass)
|
339
|
+
name = @key_strategy.call klass.model_name
|
340
|
+
get_method_for_string name
|
341
|
+
end
|
318
342
|
|
319
|
-
|
320
|
-
|
321
|
-
|
343
|
+
def get_method_for_string(str)
|
344
|
+
"#{prefix}#{str}_#{suffix}"
|
345
|
+
end
|
322
346
|
|
323
|
-
|
324
|
-
|
325
|
-
|
347
|
+
[nil, "new", "edit"].each do |action|
|
348
|
+
CACHE[:url][action] = build action, "url"
|
349
|
+
CACHE[:path][action] = build action, "path"
|
350
|
+
end
|
326
351
|
end
|
327
|
-
end
|
328
352
|
end
|
329
353
|
end
|
330
354
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_dispatch/http/request"
|
4
|
+
require "active_support/core_ext/uri"
|
5
|
+
require "active_support/core_ext/array/extract_options"
|
6
|
+
require "rack/utils"
|
7
|
+
require "action_controller/metal/exceptions"
|
8
|
+
require "action_dispatch/routing/endpoint"
|
7
9
|
|
8
10
|
module ActionDispatch
|
9
11
|
module Routing
|
@@ -22,9 +24,8 @@ module ActionDispatch
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def serve(req)
|
25
|
-
req.check_path_parameters!
|
26
27
|
uri = URI.parse(path(req.path_parameters, req))
|
27
|
-
|
28
|
+
|
28
29
|
unless uri.host
|
29
30
|
if relative_path?(uri.path)
|
30
31
|
uri.path = "#{req.script_name}/#{uri.path}"
|
@@ -32,17 +33,19 @@ module ActionDispatch
|
|
32
33
|
uri.path = req.script_name.empty? ? "/" : req.script_name
|
33
34
|
end
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
uri.scheme ||= req.scheme
|
37
38
|
uri.host ||= req.host
|
38
39
|
uri.port ||= req.port unless req.standard_port?
|
39
40
|
|
41
|
+
req.commit_flash
|
42
|
+
|
40
43
|
body = %(<html><body>You are being <a href="#{ERB::Util.unwrapped_html_escape(uri.to_s)}">redirected</a>.</body></html>)
|
41
44
|
|
42
45
|
headers = {
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
"Location" => uri.to_s,
|
47
|
+
"Content-Type" => "text/html",
|
48
|
+
"Content-Length" => body.length.to_s
|
46
49
|
}
|
47
50
|
|
48
51
|
[ status, headers, [body] ]
|
@@ -58,19 +61,19 @@ module ActionDispatch
|
|
58
61
|
|
59
62
|
private
|
60
63
|
def relative_path?(path)
|
61
|
-
path && !path.empty? && path[0] !=
|
64
|
+
path && !path.empty? && path[0] != "/"
|
62
65
|
end
|
63
66
|
|
64
67
|
def escape(params)
|
65
|
-
|
68
|
+
params.transform_values { |v| Rack::Utils.escape(v) }
|
66
69
|
end
|
67
70
|
|
68
71
|
def escape_fragment(params)
|
69
|
-
|
72
|
+
params.transform_values { |v| Journey::Router::Utils.escape_fragment(v) }
|
70
73
|
end
|
71
74
|
|
72
75
|
def escape_path(params)
|
73
|
-
|
76
|
+
params.transform_values { |v| Journey::Router::Utils.escape_path(v) }
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
@@ -104,11 +107,11 @@ module ActionDispatch
|
|
104
107
|
|
105
108
|
def path(params, request)
|
106
109
|
url_options = {
|
107
|
-
:
|
108
|
-
:
|
109
|
-
:
|
110
|
-
:
|
111
|
-
:
|
110
|
+
protocol: request.protocol,
|
111
|
+
host: request.host,
|
112
|
+
port: request.optional_port,
|
113
|
+
path: request.path,
|
114
|
+
params: request.query_parameters
|
112
115
|
}.merge! options
|
113
116
|
|
114
117
|
if !params.empty? && url_options[:path].match(/%\{\w*\}/)
|
@@ -124,26 +127,28 @@ module ActionDispatch
|
|
124
127
|
url_options[:script_name] = request.script_name
|
125
128
|
end
|
126
129
|
end
|
127
|
-
|
130
|
+
|
128
131
|
ActionDispatch::Http::URL.url_for url_options
|
129
132
|
end
|
130
133
|
|
131
134
|
def inspect
|
132
|
-
"redirect(#{status}, #{options.map{ |k,v| "#{k}: #{v}" }.join(', ')})"
|
135
|
+
"redirect(#{status}, #{options.map { |k, v| "#{k}: #{v}" }.join(', ')})"
|
133
136
|
end
|
134
137
|
end
|
135
138
|
|
136
139
|
module Redirection
|
137
|
-
|
138
140
|
# Redirect any path to another path:
|
139
141
|
#
|
140
142
|
# get "/stories" => redirect("/posts")
|
141
143
|
#
|
144
|
+
# This will redirect the user, while ignoring certain parts of the request, including query string, etc.
|
145
|
+
# <tt>/stories</tt>, <tt>/stories?foo=bar</tt>, etc all redirect to <tt>/posts</tt>.
|
146
|
+
#
|
142
147
|
# You can also use interpolation in the supplied redirect argument:
|
143
148
|
#
|
144
149
|
# get 'docs/:article', to: redirect('/wiki/%{article}')
|
145
150
|
#
|
146
|
-
# Note that if you return a path without a leading slash then the
|
151
|
+
# Note that if you return a path without a leading slash then the URL is prefixed with the
|
147
152
|
# current SCRIPT_NAME environment variable. This is typically '/' but may be different in
|
148
153
|
# a mounted engine or where the application is deployed to a subdirectory of a website.
|
149
154
|
#
|
@@ -159,14 +164,19 @@ module ActionDispatch
|
|
159
164
|
# "http://#{request.host_with_port}/#{path}"
|
160
165
|
# }
|
161
166
|
#
|
162
|
-
# Note that the
|
167
|
+
# Note that the <tt>do end</tt> syntax for the redirect block wouldn't work, as Ruby would pass
|
163
168
|
# the block to +get+ instead of +redirect+. Use <tt>{ ... }</tt> instead.
|
164
169
|
#
|
165
|
-
# The options version of redirect allows you to supply only the parts of the
|
170
|
+
# The options version of redirect allows you to supply only the parts of the URL which need
|
166
171
|
# to change, it also supports interpolation of the path similar to the first example.
|
167
172
|
#
|
168
173
|
# get 'stores/:name', to: redirect(subdomain: 'stores', path: '/%{name}')
|
169
174
|
# get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}')
|
175
|
+
# get '/stories', to: redirect(path: '/posts')
|
176
|
+
#
|
177
|
+
# This will redirect the user, while changing only the specified parts of the request,
|
178
|
+
# for example the +path+ option in the last example.
|
179
|
+
# <tt>/stories</tt>, <tt>/stories?foo=bar</tt>, redirect to <tt>/posts</tt> and <tt>/posts?foo=bar</tt> respectively.
|
170
180
|
#
|
171
181
|
# Finally, an object which responds to call can be supplied to redirect, allowing you to reuse
|
172
182
|
# common redirect routes. The call method must accept two arguments, params and request, and return
|