actionpack 4.2.10 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +553 -401
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller/base.rb +28 -38
  6. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
  7. data/lib/abstract_controller/caching.rb +62 -0
  8. data/lib/abstract_controller/callbacks.rb +52 -19
  9. data/lib/abstract_controller/collector.rb +4 -9
  10. data/lib/abstract_controller/error.rb +4 -0
  11. data/lib/abstract_controller/helpers.rb +4 -3
  12. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  13. data/lib/abstract_controller/rendering.rb +28 -18
  14. data/lib/abstract_controller/translation.rb +8 -7
  15. data/lib/abstract_controller.rb +6 -2
  16. data/lib/action_controller/api/api_rendering.rb +14 -0
  17. data/lib/action_controller/api.rb +147 -0
  18. data/lib/action_controller/base.rb +10 -13
  19. data/lib/action_controller/caching.rb +13 -58
  20. data/lib/action_controller/form_builder.rb +48 -0
  21. data/lib/action_controller/log_subscriber.rb +3 -10
  22. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  23. data/lib/action_controller/metal/conditional_get.rb +106 -34
  24. data/lib/action_controller/metal/cookies.rb +1 -3
  25. data/lib/action_controller/metal/data_streaming.rb +11 -32
  26. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  27. data/lib/action_controller/metal/exceptions.rb +11 -6
  28. data/lib/action_controller/metal/force_ssl.rb +10 -10
  29. data/lib/action_controller/metal/head.rb +14 -8
  30. data/lib/action_controller/metal/helpers.rb +15 -6
  31. data/lib/action_controller/metal/http_authentication.rb +44 -35
  32. data/lib/action_controller/metal/implicit_render.rb +61 -6
  33. data/lib/action_controller/metal/instrumentation.rb +5 -5
  34. data/lib/action_controller/metal/live.rb +66 -88
  35. data/lib/action_controller/metal/mime_responds.rb +27 -42
  36. data/lib/action_controller/metal/params_wrapper.rb +8 -8
  37. data/lib/action_controller/metal/redirecting.rb +32 -9
  38. data/lib/action_controller/metal/renderers.rb +85 -40
  39. data/lib/action_controller/metal/rendering.rb +38 -6
  40. data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
  41. data/lib/action_controller/metal/rescue.rb +3 -12
  42. data/lib/action_controller/metal/streaming.rb +4 -4
  43. data/lib/action_controller/metal/strong_parameters.rb +293 -90
  44. data/lib/action_controller/metal/testing.rb +1 -12
  45. data/lib/action_controller/metal/url_for.rb +12 -5
  46. data/lib/action_controller/metal.rb +88 -63
  47. data/lib/action_controller/renderer.rb +111 -0
  48. data/lib/action_controller/template_assertions.rb +9 -0
  49. data/lib/action_controller/test_case.rb +288 -368
  50. data/lib/action_controller.rb +12 -9
  51. data/lib/action_dispatch/http/cache.rb +73 -34
  52. data/lib/action_dispatch/http/filter_parameters.rb +15 -11
  53. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  54. data/lib/action_dispatch/http/headers.rb +44 -13
  55. data/lib/action_dispatch/http/mime_negotiation.rb +41 -23
  56. data/lib/action_dispatch/http/mime_type.rb +126 -90
  57. data/lib/action_dispatch/http/mime_types.rb +3 -4
  58. data/lib/action_dispatch/http/parameter_filter.rb +18 -8
  59. data/lib/action_dispatch/http/parameters.rb +54 -41
  60. data/lib/action_dispatch/http/request.rb +149 -82
  61. data/lib/action_dispatch/http/response.rb +206 -102
  62. data/lib/action_dispatch/http/url.rb +117 -8
  63. data/lib/action_dispatch/journey/formatter.rb +39 -28
  64. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  65. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  66. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  67. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  68. data/lib/action_dispatch/journey/parser_extras.rb +4 -0
  69. data/lib/action_dispatch/journey/path/pattern.rb +38 -42
  70. data/lib/action_dispatch/journey/route.rb +74 -19
  71. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  72. data/lib/action_dispatch/journey/router.rb +5 -9
  73. data/lib/action_dispatch/journey/routes.rb +14 -15
  74. data/lib/action_dispatch/journey/visitors.rb +86 -43
  75. data/lib/action_dispatch/middleware/callbacks.rb +10 -1
  76. data/lib/action_dispatch/middleware/cookies.rb +189 -135
  77. data/lib/action_dispatch/middleware/debug_exceptions.rb +124 -49
  78. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
  79. data/lib/action_dispatch/middleware/executor.rb +19 -0
  80. data/lib/action_dispatch/middleware/flash.rb +66 -45
  81. data/lib/action_dispatch/middleware/params_parser.rb +32 -46
  82. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  83. data/lib/action_dispatch/middleware/reloader.rb +14 -58
  84. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  85. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  86. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  87. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  88. data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
  89. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  90. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  91. data/lib/action_dispatch/middleware/ssl.rb +115 -36
  92. data/lib/action_dispatch/middleware/stack.rb +44 -40
  93. data/lib/action_dispatch/middleware/static.rb +51 -35
  94. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  95. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  96. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  97. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  98. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  99. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  100. data/lib/action_dispatch/railtie.rb +2 -2
  101. data/lib/action_dispatch/request/session.rb +69 -33
  102. data/lib/action_dispatch/request/utils.rb +51 -19
  103. data/lib/action_dispatch/routing/inspector.rb +32 -43
  104. data/lib/action_dispatch/routing/mapper.rb +491 -338
  105. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  106. data/lib/action_dispatch/routing/redirection.rb +3 -3
  107. data/lib/action_dispatch/routing/route_set.rb +145 -238
  108. data/lib/action_dispatch/routing/url_for.rb +27 -10
  109. data/lib/action_dispatch/routing.rb +17 -13
  110. data/lib/action_dispatch/testing/assertion_response.rb +45 -0
  111. data/lib/action_dispatch/testing/assertions/response.rb +38 -20
  112. data/lib/action_dispatch/testing/assertions/routing.rb +11 -10
  113. data/lib/action_dispatch/testing/assertions.rb +1 -1
  114. data/lib/action_dispatch/testing/integration.rb +368 -97
  115. data/lib/action_dispatch/testing/test_process.rb +5 -6
  116. data/lib/action_dispatch/testing/test_request.rb +22 -31
  117. data/lib/action_dispatch/testing/test_response.rb +7 -4
  118. data/lib/action_dispatch.rb +3 -1
  119. data/lib/action_pack/gem_version.rb +3 -3
  120. data/lib/action_pack.rb +1 -1
  121. metadata +30 -34
  122. data/lib/action_controller/metal/hide_actions.rb +0 -40
  123. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  124. data/lib/action_controller/middleware.rb +0 -39
  125. data/lib/action_controller/model_naming.rb +0 -12
  126. data/lib/action_dispatch/journey/backwards.rb +0 -5
  127. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  128. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  129. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  130. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
  131. /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -1,11 +1,9 @@
1
1
  require 'action_dispatch/journey'
2
- require 'forwardable'
3
2
  require 'active_support/concern'
4
3
  require 'active_support/core_ext/object/to_query'
5
4
  require 'active_support/core_ext/hash/slice'
6
5
  require 'active_support/core_ext/module/remove_method'
7
6
  require 'active_support/core_ext/array/extract_options'
8
- require 'active_support/core_ext/string/filters'
9
7
  require 'action_controller/metal/exceptions'
10
8
  require 'action_dispatch/http/request'
11
9
  require 'action_dispatch/routing/endpoint'
@@ -20,67 +18,48 @@ module ActionDispatch
20
18
  # alias inspect to to_s.
21
19
  alias inspect to_s
22
20
 
23
- mattr_accessor :relative_url_root
24
-
25
21
  class Dispatcher < Routing::Endpoint
26
- def initialize(defaults)
27
- @defaults = defaults
22
+ def initialize(raise_on_name_error)
23
+ @raise_on_name_error = raise_on_name_error
28
24
  end
29
25
 
30
26
  def dispatcher?; true; end
31
27
 
32
28
  def serve(req)
33
- req.check_path_parameters!
34
- params = req.path_parameters
35
-
36
- prepare_params!(params)
37
-
38
- # Just raise undefined constant errors if a controller was specified as default.
39
- unless controller = controller(params, @defaults.key?(:controller))
29
+ params = req.path_parameters
30
+ controller = controller req
31
+ res = controller.make_response! req
32
+ dispatch(controller, params[:action], req, res)
33
+ rescue ActionController::RoutingError
34
+ if @raise_on_name_error
35
+ raise
36
+ else
40
37
  return [404, {'X-Cascade' => 'pass'}, []]
41
38
  end
42
-
43
- dispatch(controller, params[:action], req.env)
44
39
  end
45
40
 
46
- def prepare_params!(params)
47
- normalize_controller!(params)
48
- merge_default_action!(params)
49
- end
41
+ private
50
42
 
51
- # If this is a default_controller (i.e. a controller specified by the user)
52
- # we should raise an error in case it's not found, because it usually means
53
- # a user error. However, if the controller was retrieved through a dynamic
54
- # segment, as in :controller(/:action), we should simply return nil and
55
- # delegate the control back to Rack cascade. Besides, if this is not a default
56
- # controller, it means we should respect the @scope[:module] parameter.
57
- def controller(params, default_controller=true)
58
- if params && params.key?(:controller)
59
- controller_param = params[:controller]
60
- controller_reference(controller_param)
61
- end
43
+ def controller(req)
44
+ req.controller_class
62
45
  rescue NameError => e
63
- raise ActionController::RoutingError, e.message, e.backtrace if default_controller
46
+ raise ActionController::RoutingError, e.message, e.backtrace
64
47
  end
65
48
 
66
- private
67
-
68
- def controller_reference(controller_param)
69
- const_name = "#{controller_param.camelize}Controller"
70
- ActiveSupport::Dependencies.constantize(const_name)
49
+ def dispatch(controller, action, req, res)
50
+ controller.dispatch(action, req, res)
71
51
  end
52
+ end
72
53
 
73
- def dispatch(controller, action, env)
74
- controller.action(action).call(env)
54
+ class StaticDispatcher < Dispatcher
55
+ def initialize(controller_class)
56
+ super(false)
57
+ @controller_class = controller_class
75
58
  end
76
59
 
77
- def normalize_controller!(params)
78
- params[:controller] = params[:controller].underscore if params.key?(:controller)
79
- end
60
+ private
80
61
 
81
- def merge_default_action!(params)
82
- params[:action] ||= 'index'
83
- end
62
+ def controller(_); @controller_class; end
84
63
  end
85
64
 
86
65
  # A NamedRouteCollection instance is a collection of named routes, and also
@@ -88,7 +67,8 @@ module ActionDispatch
88
67
  # named routes.
89
68
  class NamedRouteCollection
90
69
  include Enumerable
91
- attr_reader :routes, :url_helpers_module
70
+ attr_reader :routes, :url_helpers_module, :path_helpers_module
71
+ private :routes
92
72
 
93
73
  def initialize
94
74
  @routes = {}
@@ -103,14 +83,6 @@ module ActionDispatch
103
83
  @path_helpers.include?(key) || @url_helpers.include?(key)
104
84
  end
105
85
 
106
- def helpers
107
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
108
- `named_routes.helpers` is deprecated, please use `route_defined?(route_name)`
109
- to see if a named route was defined.
110
- MSG
111
- @path_helpers + @url_helpers
112
- end
113
-
114
86
  def helper_names
115
87
  @path_helpers.map(&:to_s) + @url_helpers.map(&:to_s)
116
88
  end
@@ -139,7 +111,7 @@ module ActionDispatch
139
111
  @url_helpers_module.send :undef_method, url_name
140
112
  end
141
113
  routes[key] = route
142
- define_url_helper @path_helpers_module, route, path_name, route.defaults, name, LEGACY
114
+ define_url_helper @path_helpers_module, route, path_name, route.defaults, name, PATH
143
115
  define_url_helper @url_helpers_module, route, url_name, route.defaults, name, UNKNOWN
144
116
 
145
117
  @path_helpers << path_name
@@ -151,6 +123,7 @@ module ActionDispatch
151
123
  end
152
124
 
153
125
  def key?(name)
126
+ return unless name
154
127
  routes.key? name.to_sym
155
128
  end
156
129
 
@@ -171,25 +144,6 @@ module ActionDispatch
171
144
  routes.length
172
145
  end
173
146
 
174
- def path_helpers_module(warn = false)
175
- if warn
176
- mod = @path_helpers_module
177
- helpers = @path_helpers
178
- Module.new do
179
- include mod
180
-
181
- helpers.each do |meth|
182
- define_method(meth) do |*args, &block|
183
- ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead")
184
- super(*args, &block)
185
- end
186
- end
187
- end
188
- else
189
- @path_helpers_module
190
- end
191
- end
192
-
193
147
  class UrlHelper
194
148
  def self.create(route, options, route_name, url_strategy)
195
149
  if optimize_helper?(route)
@@ -227,11 +181,8 @@ module ActionDispatch
227
181
  private
228
182
 
229
183
  def optimized_helper(args)
230
- params = parameterize_args(args)
231
- missing_keys = missing_keys(params)
232
-
233
- unless missing_keys.empty?
234
- raise_generation_error(params, missing_keys)
184
+ params = parameterize_args(args) do
185
+ raise_generation_error(args)
235
186
  end
236
187
 
237
188
  @route.format params
@@ -243,16 +194,21 @@ module ActionDispatch
243
194
 
244
195
  def parameterize_args(args)
245
196
  params = {}
246
- @required_parts.zip(args.map(&:to_param)) { |k,v| params[k] = v }
197
+ @arg_size.times { |i|
198
+ key = @required_parts[i]
199
+ value = args[i].to_param
200
+ yield key if value.nil? || value.empty?
201
+ params[key] = value
202
+ }
247
203
  params
248
204
  end
249
205
 
250
- def missing_keys(args)
251
- args.select{ |part, arg| arg.nil? || arg.empty? }.keys
252
- end
253
-
254
- def raise_generation_error(args, missing_keys)
255
- constraints = Hash[@route.requirements.merge(args).sort_by{|k,v| k.to_s}]
206
+ def raise_generation_error(args)
207
+ missing_keys = []
208
+ params = parameterize_args(args) { |missing_key|
209
+ missing_keys << missing_key
210
+ }
211
+ constraints = Hash[@route.requirements.merge(params).sort_by{|k,v| k.to_s}]
256
212
  message = "No route matches #{constraints.inspect}"
257
213
  message << " missing required keys: #{missing_keys.sort.inspect}"
258
214
 
@@ -272,7 +228,7 @@ module ActionDispatch
272
228
  controller_options = t.url_options
273
229
  options = controller_options.merge @options
274
230
  hash = handle_positional_args(controller_options,
275
- deprecate_string_options(inner_options) || {},
231
+ inner_options || {},
276
232
  args,
277
233
  options,
278
234
  @segment_keys)
@@ -293,33 +249,18 @@ module ActionDispatch
293
249
  path_params -= controller_options.keys
294
250
  path_params -= result.keys
295
251
  end
296
- path_params.each { |param|
297
- value = inner_options.fetch(param) { args.shift }
252
+ inner_options.each_key do |key|
253
+ path_params.delete(key)
254
+ end
298
255
 
299
- unless param == :format && value.nil?
300
- result[param] = value
301
- end
302
- }
256
+ args.each_with_index do |arg, index|
257
+ param = path_params[index]
258
+ result[param] = arg if param
259
+ end
303
260
  end
304
261
 
305
262
  result.merge!(inner_options)
306
263
  end
307
-
308
- DEPRECATED_STRING_OPTIONS = %w[controller action]
309
-
310
- def deprecate_string_options(options)
311
- options ||= {}
312
- deprecated_string_options = options.keys & DEPRECATED_STRING_OPTIONS
313
- if deprecated_string_options.any?
314
- msg = "Calling URL helpers with string keys #{deprecated_string_options.join(", ")} is deprecated. Use symbols instead."
315
- ActiveSupport::Deprecation.warn(msg)
316
- deprecated_string_options.each do |option|
317
- value = options.delete(option)
318
- options[option.to_sym] = value
319
- end
320
- end
321
- options
322
- end
323
264
  end
324
265
 
325
266
  private
@@ -340,8 +281,17 @@ module ActionDispatch
340
281
  helper = UrlHelper.create(route, opts, route_key, url_strategy)
341
282
  mod.module_eval do
342
283
  define_method(name) do |*args|
343
- options = nil
344
- options = args.pop if args.last.is_a? Hash
284
+ last = args.last
285
+ options = case last
286
+ when Hash
287
+ args.pop
288
+ when ActionController::Parameters
289
+ if last.permitted?
290
+ args.pop.to_h
291
+ else
292
+ raise ArgumentError, ActionDispatch::Routing::INSECURE_URL_PARAMETERS_MESSAGE
293
+ end
294
+ end
345
295
  helper.call self, args, options
346
296
  end
347
297
  end
@@ -350,38 +300,12 @@ module ActionDispatch
350
300
 
351
301
  # strategy for building urls to send to the client
352
302
  PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
353
- FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
354
303
  UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) }
355
- LEGACY = ->(options) {
356
- if options.key?(:only_path)
357
- if options[:only_path]
358
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
359
- You are calling a `*_path` helper with the `only_path` option
360
- explicitly set to `true`. This option will stop working on
361
- path helpers in Rails 5. Simply remove the `only_path: true`
362
- argument from your call as it is redundant when applied to a
363
- path helper.
364
- MSG
365
-
366
- PATH.call(options)
367
- else
368
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
369
- You are calling a `*_path` helper with the `only_path` option
370
- explicitly set to `false`. This option will stop working on
371
- path helpers in Rails 5. Use the corresponding `*_url` helper
372
- instead.
373
- MSG
374
-
375
- FULL.call(options)
376
- end
377
- else
378
- PATH.call(options)
379
- end
380
- }
381
304
 
382
305
  attr_accessor :formatter, :set, :named_routes, :default_scope, :router
383
306
  attr_accessor :disable_clear_and_finalize, :resources_path_names
384
- attr_accessor :default_url_options, :request_class
307
+ attr_accessor :default_url_options
308
+ attr_reader :env_key
385
309
 
386
310
  alias :routes :set
387
311
 
@@ -389,21 +313,58 @@ module ActionDispatch
389
313
  { :new => 'new', :edit => 'edit' }
390
314
  end
391
315
 
392
- def initialize(request_class = ActionDispatch::Request)
316
+ def self.new_with_config(config)
317
+ route_set_config = DEFAULT_CONFIG
318
+
319
+ # engines apparently don't have this set
320
+ if config.respond_to? :relative_url_root
321
+ route_set_config.relative_url_root = config.relative_url_root
322
+ end
323
+
324
+ if config.respond_to? :api_only
325
+ route_set_config.api_only = config.api_only
326
+ end
327
+
328
+ new route_set_config
329
+ end
330
+
331
+ Config = Struct.new :relative_url_root, :api_only
332
+
333
+ DEFAULT_CONFIG = Config.new(nil, false)
334
+
335
+ def initialize(config = DEFAULT_CONFIG)
393
336
  self.named_routes = NamedRouteCollection.new
394
337
  self.resources_path_names = self.class.default_resources_path_names
395
338
  self.default_url_options = {}
396
- self.request_class = request_class
397
339
 
340
+ @config = config
398
341
  @append = []
399
342
  @prepend = []
400
343
  @disable_clear_and_finalize = false
401
344
  @finalized = false
345
+ @env_key = "ROUTES_#{object_id}_SCRIPT_NAME".freeze
402
346
 
403
347
  @set = Journey::Routes.new
404
348
  @router = Journey::Router.new @set
405
- @formatter = Journey::Formatter.new @set
349
+ @formatter = Journey::Formatter.new self
350
+ end
351
+
352
+ def relative_url_root
353
+ @config.relative_url_root
354
+ end
355
+
356
+ def api_only?
357
+ @config.api_only
358
+ end
359
+
360
+ def request_class
361
+ ActionDispatch::Request
362
+ end
363
+
364
+ def make_request(env)
365
+ request_class.new env
406
366
  end
367
+ private :make_request
407
368
 
408
369
  def draw(&block)
409
370
  clear! unless @disable_clear_and_finalize
@@ -421,10 +382,6 @@ module ActionDispatch
421
382
  end
422
383
 
423
384
  def eval_block(block)
424
- if block.arity == 1
425
- raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
426
- "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
427
- end
428
385
  mapper = Mapper.new(self)
429
386
  if default_scope
430
387
  mapper.with_default_scope(default_scope, &block)
@@ -448,10 +405,6 @@ module ActionDispatch
448
405
  @prepend.each { |blk| eval_block(blk) }
449
406
  end
450
407
 
451
- def dispatcher(defaults)
452
- Routing::RouteSet::Dispatcher.new(defaults)
453
- end
454
-
455
408
  module MountedHelpers
456
409
  extend ActiveSupport::Concern
457
410
  include UrlFor
@@ -495,7 +448,14 @@ module ActionDispatch
495
448
  # Rails.application.routes.url_helpers.url_for(args)
496
449
  @_routes = routes
497
450
  class << self
498
- delegate :url_for, :optimize_routes_generation?, to: '@_routes'
451
+ def url_for(options)
452
+ @_routes.url_for(options)
453
+ end
454
+
455
+ def optimize_routes_generation?
456
+ @_routes.optimize_routes_generation?
457
+ end
458
+
499
459
  attr_reader :_routes
500
460
  def url_options; {}; end
501
461
  end
@@ -513,12 +473,10 @@ module ActionDispatch
513
473
 
514
474
  if supports_path
515
475
  path_helpers = routes.named_routes.path_helpers_module
516
- else
517
- path_helpers = routes.named_routes.path_helpers_module(true)
518
- end
519
476
 
520
- include path_helpers
521
- extend path_helpers
477
+ include path_helpers
478
+ extend path_helpers
479
+ end
522
480
 
523
481
  # plus a singleton class method called _routes ...
524
482
  included do
@@ -542,7 +500,7 @@ module ActionDispatch
542
500
  routes.empty?
543
501
  end
544
502
 
545
- def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
503
+ def add_route(mapping, path_ast, name, anchor)
546
504
  raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
547
505
 
548
506
  if name && named_routes[name]
@@ -553,74 +511,32 @@ module ActionDispatch
553
511
  "http://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
554
512
  end
555
513
 
556
- path = conditions.delete :path_info
557
- ast = conditions.delete :parsed_path_info
558
- path = build_path(path, ast, requirements, anchor)
559
- conditions = build_conditions(conditions, path.names.map { |x| x.to_sym })
560
-
561
- route = @set.add_route(app, path, conditions, defaults, name)
514
+ route = @set.add_route(name, mapping)
562
515
  named_routes[name] = route if name
563
- route
564
- end
565
-
566
- def build_path(path, ast, requirements, anchor)
567
- strexp = Journey::Router::Strexp.new(
568
- ast,
569
- path,
570
- requirements,
571
- SEPARATORS,
572
- anchor)
573
-
574
- pattern = Journey::Path::Pattern.new(strexp)
575
516
 
576
- builder = Journey::GTG::Builder.new pattern.spec
577
-
578
- # Get all the symbol nodes followed by literals that are not the
579
- # dummy node.
580
- symbols = pattern.spec.grep(Journey::Nodes::Symbol).find_all { |n|
581
- builder.followpos(n).first.literal?
582
- }
583
-
584
- # Get all the symbol nodes preceded by literals.
585
- symbols.concat pattern.spec.find_all(&:literal?).map { |n|
586
- builder.followpos(n).first
587
- }.find_all(&:symbol?)
588
-
589
- symbols.each { |x|
590
- x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/
591
- }
592
-
593
- pattern
594
- end
595
- private :build_path
596
-
597
- def build_conditions(current_conditions, path_values)
598
- conditions = current_conditions.dup
599
-
600
- # Rack-Mount requires that :request_method be a regular expression.
601
- # :request_method represents the HTTP verb that matches this route.
602
- #
603
- # Here we munge values before they get sent on to rack-mount.
604
- verbs = conditions[:request_method] || []
605
- unless verbs.empty?
606
- conditions[:request_method] = %r[^#{verbs.join('|')}$]
517
+ if route.segment_keys.include?(:controller)
518
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
519
+ Using a dynamic :controller segment in a route is deprecated and
520
+ will be removed in Rails 5.1.
521
+ MSG
607
522
  end
608
523
 
609
- conditions.keep_if do |k, _|
610
- k == :action || k == :controller || k == :required_defaults ||
611
- @request_class.public_method_defined?(k) || path_values.include?(k)
524
+ if route.segment_keys.include?(:action)
525
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
526
+ Using a dynamic :action segment in a route is deprecated and
527
+ will be removed in Rails 5.1.
528
+ MSG
612
529
  end
530
+
531
+ route
613
532
  end
614
- private :build_conditions
615
533
 
616
534
  class Generator
617
535
  PARAMETERIZE = lambda do |name, value|
618
536
  if name == :controller
619
537
  value
620
- elsif value.is_a?(Array)
621
- value.map { |v| v.to_param }.join('/')
622
- elsif param = value.to_param
623
- param
538
+ else
539
+ value.to_param
624
540
  end
625
541
  end
626
542
 
@@ -628,16 +544,14 @@ module ActionDispatch
628
544
 
629
545
  def initialize(named_route, options, recall, set)
630
546
  @named_route = named_route
631
- @options = options.dup
632
- @recall = recall.dup
547
+ @options = options
548
+ @recall = recall
633
549
  @set = set
634
550
 
635
- normalize_recall!
636
551
  normalize_options!
637
552
  normalize_controller_action_id!
638
553
  use_relative_controller!
639
554
  normalize_controller!
640
- normalize_action!
641
555
  end
642
556
 
643
557
  def controller
@@ -651,16 +565,11 @@ module ActionDispatch
651
565
  def use_recall_for(key)
652
566
  if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
653
567
  if !named_route_exists? || segment_keys.include?(key)
654
- @options[key] = @recall.delete(key)
568
+ @options[key] = @recall[key]
655
569
  end
656
570
  end
657
571
  end
658
572
 
659
- # Set 'index' as default action for recall
660
- def normalize_recall!
661
- @recall[:action] ||= 'index'
662
- end
663
-
664
573
  def normalize_options!
665
574
  # If an explicit :controller was given, always make :action explicit
666
575
  # too, so that action expiry works as expected for things like
@@ -705,13 +614,12 @@ module ActionDispatch
705
614
 
706
615
  # Remove leading slashes from controllers
707
616
  def normalize_controller!
708
- @options[:controller] = controller.sub(%r{^/}, '') if controller
709
- end
710
-
711
- # Move 'index' action from options to recall
712
- def normalize_action!
713
- if @options[:action] == 'index'
714
- @recall[:action] = @options.delete(:action)
617
+ if controller
618
+ if controller.start_with?("/".freeze)
619
+ @options[:controller] = controller[1..-1]
620
+ else
621
+ @options[:controller] = controller
622
+ end
715
623
  end
716
624
  end
717
625
 
@@ -812,7 +720,7 @@ module ActionDispatch
812
720
  end
813
721
 
814
722
  def call(env)
815
- req = request_class.new(env)
723
+ req = make_request(env)
816
724
  req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
817
725
  @router.serve(req)
818
726
  end
@@ -828,7 +736,7 @@ module ActionDispatch
828
736
  raise ActionController::RoutingError, e.message
829
737
  end
830
738
 
831
- req = request_class.new(env)
739
+ req = make_request(env)
832
740
  @router.recognize(req) do |route, params|
833
741
  params.merge!(extras)
834
742
  params.each do |key, value|
@@ -841,14 +749,13 @@ module ActionDispatch
841
749
  req.path_parameters = old_params.merge params
842
750
  app = route.app
843
751
  if app.matches?(req) && app.dispatcher?
844
- dispatcher = app.app
845
-
846
- if dispatcher.controller(params, false)
847
- dispatcher.prepare_params!(params)
848
- return params
849
- else
752
+ begin
753
+ req.controller_class
754
+ rescue NameError
850
755
  raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller"
851
756
  end
757
+
758
+ return req.path_parameters
852
759
  end
853
760
  end
854
761