actionpack 4.2.11.1 → 6.1.3.2

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.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +291 -489
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +81 -51
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +61 -33
  10. data/lib/abstract_controller/collector.rb +9 -13
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +115 -99
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
  15. data/lib/abstract_controller/rendering.rb +48 -47
  16. data/lib/abstract_controller/translation.rb +17 -8
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +13 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/base.rb +29 -24
  22. data/lib/action_controller/caching.rb +12 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +17 -19
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +134 -46
  27. data/lib/action_controller/metal/content_security_policy.rb +51 -0
  28. data/lib/action_controller/metal/cookies.rb +6 -4
  29. data/lib/action_controller/metal/data_streaming.rb +30 -50
  30. data/lib/action_controller/metal/default_headers.rb +17 -0
  31. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
  33. data/lib/action_controller/metal/exceptions.rb +63 -15
  34. data/lib/action_controller/metal/flash.rb +9 -8
  35. data/lib/action_controller/metal/head.rb +26 -21
  36. data/lib/action_controller/metal/helpers.rb +37 -18
  37. data/lib/action_controller/metal/http_authentication.rb +81 -73
  38. data/lib/action_controller/metal/implicit_render.rb +53 -9
  39. data/lib/action_controller/metal/instrumentation.rb +32 -35
  40. data/lib/action_controller/metal/live.rb +102 -120
  41. data/lib/action_controller/metal/logging.rb +20 -0
  42. data/lib/action_controller/metal/mime_responds.rb +49 -47
  43. data/lib/action_controller/metal/parameter_encoding.rb +82 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +83 -66
  45. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  46. data/lib/action_controller/metal/redirecting.rb +53 -32
  47. data/lib/action_controller/metal/renderers.rb +87 -44
  48. data/lib/action_controller/metal/rendering.rb +77 -50
  49. data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
  50. data/lib/action_controller/metal/rescue.rb +10 -17
  51. data/lib/action_controller/metal/streaming.rb +12 -11
  52. data/lib/action_controller/metal/strong_parameters.rb +714 -186
  53. data/lib/action_controller/metal/testing.rb +2 -17
  54. data/lib/action_controller/metal/url_for.rb +19 -10
  55. data/lib/action_controller/metal.rb +104 -87
  56. data/lib/action_controller/railtie.rb +28 -10
  57. data/lib/action_controller/railties/helpers.rb +3 -1
  58. data/lib/action_controller/renderer.rb +141 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +296 -422
  61. data/lib/action_controller.rb +34 -23
  62. data/lib/action_dispatch/http/cache.rb +107 -56
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +286 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +32 -25
  66. data/lib/action_dispatch/http/filter_redirect.rb +10 -12
  67. data/lib/action_dispatch/http/headers.rb +55 -22
  68. data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
  69. data/lib/action_dispatch/http/mime_type.rb +153 -121
  70. data/lib/action_dispatch/http/mime_types.rb +20 -6
  71. data/lib/action_dispatch/http/parameters.rb +90 -40
  72. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  74. data/lib/action_dispatch/http/request.rb +226 -121
  75. data/lib/action_dispatch/http/response.rb +248 -113
  76. data/lib/action_dispatch/http/upload.rb +21 -7
  77. data/lib/action_dispatch/http/url.rb +182 -100
  78. data/lib/action_dispatch/journey/formatter.rb +90 -43
  79. data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
  80. data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
  81. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
  82. data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
  83. data/lib/action_dispatch/journey/nodes/node.rb +29 -15
  84. data/lib/action_dispatch/journey/parser.rb +17 -16
  85. data/lib/action_dispatch/journey/parser.y +4 -3
  86. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  87. data/lib/action_dispatch/journey/path/pattern.rb +58 -54
  88. data/lib/action_dispatch/journey/route.rb +100 -32
  89. data/lib/action_dispatch/journey/router/utils.rb +29 -18
  90. data/lib/action_dispatch/journey/router.rb +55 -51
  91. data/lib/action_dispatch/journey/routes.rb +17 -17
  92. data/lib/action_dispatch/journey/scanner.rb +26 -17
  93. data/lib/action_dispatch/journey/visitors.rb +98 -54
  94. data/lib/action_dispatch/journey.rb +5 -5
  95. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  96. data/lib/action_dispatch/middleware/callbacks.rb +3 -6
  97. data/lib/action_dispatch/middleware/cookies.rb +347 -217
  98. data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
  99. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  100. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  101. data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
  102. data/lib/action_dispatch/middleware/executor.rb +21 -0
  103. data/lib/action_dispatch/middleware/flash.rb +78 -54
  104. data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
  106. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  107. data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
  108. data/lib/action_dispatch/middleware/request_id.rb +17 -10
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
  114. data/lib/action_dispatch/middleware/ssl.rb +118 -35
  115. data/lib/action_dispatch/middleware/stack.rb +82 -41
  116. data/lib/action_dispatch/middleware/static.rb +156 -89
  117. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
  121. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  125. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  129. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  135. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  137. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  138. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  139. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  140. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
  141. data/lib/action_dispatch/railtie.rb +27 -13
  142. data/lib/action_dispatch/request/session.rb +109 -61
  143. data/lib/action_dispatch/request/utils.rb +90 -23
  144. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  145. data/lib/action_dispatch/routing/inspector.rb +141 -102
  146. data/lib/action_dispatch/routing/mapper.rb +811 -473
  147. data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
  148. data/lib/action_dispatch/routing/redirection.rb +37 -27
  149. data/lib/action_dispatch/routing/route_set.rb +363 -331
  150. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  151. data/lib/action_dispatch/routing/url_for.rb +66 -26
  152. data/lib/action_dispatch/routing.rb +36 -36
  153. data/lib/action_dispatch/system_test_case.rb +190 -0
  154. data/lib/action_dispatch/system_testing/browser.rb +86 -0
  155. data/lib/action_dispatch/system_testing/driver.rb +67 -0
  156. data/lib/action_dispatch/system_testing/server.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
  158. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
  159. data/lib/action_dispatch/testing/assertion_response.rb +46 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +44 -22
  161. data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
  162. data/lib/action_dispatch/testing/assertions.rb +6 -4
  163. data/lib/action_dispatch/testing/integration.rb +391 -220
  164. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  165. data/lib/action_dispatch/testing/test_process.rb +53 -22
  166. data/lib/action_dispatch/testing/test_request.rb +27 -34
  167. data/lib/action_dispatch/testing/test_response.rb +11 -11
  168. data/lib/action_dispatch.rb +35 -21
  169. data/lib/action_pack/gem_version.rb +6 -4
  170. data/lib/action_pack/version.rb +3 -1
  171. data/lib/action_pack.rb +4 -2
  172. metadata +78 -48
  173. data/lib/action_controller/metal/force_ssl.rb +0 -97
  174. data/lib/action_controller/metal/hide_actions.rb +0 -40
  175. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  176. data/lib/action_controller/middleware.rb +0 -39
  177. data/lib/action_controller/model_naming.rb +0 -12
  178. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  179. data/lib/action_dispatch/journey/backwards.rb +0 -5
  180. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  181. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  182. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  183. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  184. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  185. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  186. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  187. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,4 +1,4 @@
1
- require 'action_controller/model_naming'
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) # => "/posts/1/edit"
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 <tt>url_for</tt>.
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. It uses
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
- def polymorphic_url_for_action(action, record_or_hash, options)
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 self.url; CACHE['url'.freeze][nil]; end
173
- def self.path; CACHE['path'.freeze][nil]; end
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 self.build(action, type)
176
- prefix = action ? "#{action}_" : ""
177
- suffix = type
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
- HelperMethodBuilder.plural prefix, suffix
172
+ _routes.polymorphic_mappings[record.class.name]
182
173
  end
183
174
  end
184
175
 
185
- def self.singular(prefix, suffix)
186
- new(->(name) { name.singular_route_key }, prefix, suffix)
187
- end
176
+ class HelperMethodBuilder # :nodoc:
177
+ CACHE = { path: {}, url: {} }
188
178
 
189
- def self.plural(prefix, suffix)
190
- new(->(name) { name.route_key }, prefix, suffix)
191
- end
179
+ def self.get(action, type)
180
+ type = type.to_sym
181
+ CACHE[type].fetch(action) { build action, type }
182
+ end
192
183
 
193
- def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
194
- builder = get action, type
184
+ def self.url; CACHE[:url][nil]; end
185
+ def self.path; CACHE[:path][nil]; end
195
186
 
196
- case record_or_hash_or_array
197
- when Array
198
- record_or_hash_or_array = record_or_hash_or_array.compact
199
- if record_or_hash_or_array.empty?
200
- raise ArgumentError, "Nil location provided. Can't build URI."
201
- end
202
- if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
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
- if options.empty?
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
- attr_reader :suffix, :prefix
201
+ def self.plural(prefix, suffix)
202
+ new(->(name) { name.route_key }, prefix, suffix)
203
+ end
227
204
 
228
- def initialize(key_strategy, prefix, suffix)
229
- @key_strategy = key_strategy
230
- @prefix = prefix
231
- @suffix = suffix
232
- end
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
- def handle_string(record)
235
- [get_method_for_string(record), []]
236
- end
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
- def handle_string_call(target, str)
239
- target.send get_method_for_string str
240
- end
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
- def handle_class(klass)
243
- [get_method_for_class(klass), []]
244
- end
237
+ attr_reader :suffix, :prefix
245
238
 
246
- def handle_class_call(target, klass)
247
- target.send get_method_for_class klass
248
- end
239
+ def initialize(key_strategy, prefix, suffix)
240
+ @key_strategy = key_strategy
241
+ @prefix = prefix
242
+ @suffix = suffix
243
+ end
249
244
 
250
- def handle_model(record)
251
- args = []
245
+ def handle_string(record)
246
+ [get_method_for_string(record), []]
247
+ end
252
248
 
253
- model = record.to_model
254
- name = if model.persisted?
255
- args << model
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
- named_route = prefix + "#{name}_#{suffix}"
253
+ def handle_class(klass)
254
+ [get_method_for_class(klass), []]
255
+ end
262
256
 
263
- [named_route, args]
264
- end
257
+ def handle_class_call(target, klass)
258
+ target.public_send get_method_for_class klass
259
+ end
265
260
 
266
- def handle_model_call(target, model)
267
- method, args = handle_model model
268
- target.send(method, *args)
269
- end
261
+ def handle_model(record)
262
+ args = []
270
263
 
271
- def handle_list(list)
272
- record_list = list.dup
273
- record = record_list.pop
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
- args = []
272
+ [named_route, args]
273
+ end
276
274
 
277
- route = record_list.map { |parent|
278
- case parent
279
- when Symbol, String
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 << parent.to_model
286
- parent.to_model.model_name.singular_route_key
279
+ method, args = handle_model(record)
280
+ target.public_send(method, *args)
287
281
  end
288
- }
289
-
290
- route <<
291
- case record
292
- when Symbol, String
293
- record.to_s
294
- when Class
295
- @key_strategy.call record.model_name
296
- else
297
- model = record.to_model
298
- if model.persisted?
299
- args << model
300
- model.model_name.singular_route_key
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
- @key_strategy.call model.model_name
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
- route << suffix
323
+ route << suffix
307
324
 
308
- named_route = prefix + route.join("_")
309
- [named_route, args]
310
- end
325
+ named_route = prefix + route.join("_")
326
+ [named_route, args]
327
+ end
311
328
 
312
- private
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
- def get_method_for_class(klass)
315
- name = @key_strategy.call klass.model_name
316
- prefix + "#{name}_#{suffix}"
317
- end
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
- def get_method_for_string(str)
320
- prefix + "#{str}_#{suffix}"
321
- end
343
+ def get_method_for_string(str)
344
+ "#{prefix}#{str}_#{suffix}"
345
+ end
322
346
 
323
- [nil, 'new', 'edit'].each do |action|
324
- CACHE['url'][action] = build action, 'url'
325
- CACHE['path'][action] = build action, 'path'
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
- require 'action_dispatch/http/request'
2
- require 'active_support/core_ext/uri'
3
- require 'active_support/core_ext/array/extract_options'
4
- require 'rack/utils'
5
- require 'action_controller/metal/exceptions'
6
- require 'action_dispatch/routing/endpoint'
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
- 'Location' => uri.to_s,
44
- 'Content-Type' => 'text/html',
45
- 'Content-Length' => body.length.to_s
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
- Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }]
68
+ params.transform_values { |v| Rack::Utils.escape(v) }
66
69
  end
67
70
 
68
71
  def escape_fragment(params)
69
- Hash[params.map{ |k,v| [k, Journey::Router::Utils.escape_fragment(v)] }]
72
+ params.transform_values { |v| Journey::Router::Utils.escape_fragment(v) }
70
73
  end
71
74
 
72
75
  def escape_path(params)
73
- Hash[params.map{ |k,v| [k, Journey::Router::Utils.escape_path(v)] }]
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
- :protocol => request.protocol,
108
- :host => request.host,
109
- :port => request.optional_port,
110
- :path => request.path,
111
- :params => request.query_parameters
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 url is prefixed with 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 +do end+ syntax for the redirect block wouldn't work, as Ruby would pass
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 url which need
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