actionpack 7.1.3 → 7.2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -501
  3. data/lib/abstract_controller/asset_paths.rb +2 -0
  4. data/lib/abstract_controller/base.rb +102 -98
  5. data/lib/abstract_controller/caching/fragments.rb +50 -53
  6. data/lib/abstract_controller/caching.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +66 -64
  8. data/lib/abstract_controller/collector.rb +6 -6
  9. data/lib/abstract_controller/deprecator.rb +2 -0
  10. data/lib/abstract_controller/error.rb +2 -0
  11. data/lib/abstract_controller/helpers.rb +70 -85
  12. data/lib/abstract_controller/logger.rb +2 -0
  13. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  14. data/lib/abstract_controller/rendering.rb +13 -12
  15. data/lib/abstract_controller/translation.rb +15 -7
  16. data/lib/abstract_controller/url_for.rb +8 -6
  17. data/lib/abstract_controller.rb +2 -0
  18. data/lib/action_controller/api/api_rendering.rb +2 -0
  19. data/lib/action_controller/api.rb +74 -72
  20. data/lib/action_controller/base.rb +198 -126
  21. data/lib/action_controller/caching.rb +15 -12
  22. data/lib/action_controller/deprecator.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +20 -17
  24. data/lib/action_controller/log_subscriber.rb +3 -1
  25. data/lib/action_controller/metal/allow_browser.rb +123 -0
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +188 -174
  28. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  29. data/lib/action_controller/metal/cookies.rb +4 -2
  30. data/lib/action_controller/metal/data_streaming.rb +64 -55
  31. data/lib/action_controller/metal/default_headers.rb +5 -3
  32. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  34. data/lib/action_controller/metal/exceptions.rb +11 -9
  35. data/lib/action_controller/metal/flash.rb +12 -10
  36. data/lib/action_controller/metal/head.rb +12 -10
  37. data/lib/action_controller/metal/helpers.rb +63 -55
  38. data/lib/action_controller/metal/http_authentication.rb +210 -205
  39. data/lib/action_controller/metal/implicit_render.rb +17 -15
  40. data/lib/action_controller/metal/instrumentation.rb +15 -12
  41. data/lib/action_controller/metal/live.rb +113 -107
  42. data/lib/action_controller/metal/logging.rb +6 -4
  43. data/lib/action_controller/metal/mime_responds.rb +151 -142
  44. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  45. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  46. data/lib/action_controller/metal/permissions_policy.rb +13 -12
  47. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  48. data/lib/action_controller/metal/redirecting.rb +108 -82
  49. data/lib/action_controller/metal/renderers.rb +50 -49
  50. data/lib/action_controller/metal/rendering.rb +103 -75
  51. data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
  52. data/lib/action_controller/metal/rescue.rb +11 -9
  53. data/lib/action_controller/metal/streaming.rb +138 -136
  54. data/lib/action_controller/metal/strong_parameters.rb +525 -480
  55. data/lib/action_controller/metal/testing.rb +2 -0
  56. data/lib/action_controller/metal/url_for.rb +17 -15
  57. data/lib/action_controller/metal.rb +86 -60
  58. data/lib/action_controller/railtie.rb +3 -0
  59. data/lib/action_controller/railties/helpers.rb +2 -0
  60. data/lib/action_controller/renderer.rb +42 -36
  61. data/lib/action_controller/template_assertions.rb +4 -2
  62. data/lib/action_controller/test_case.rb +146 -126
  63. data/lib/action_controller.rb +10 -3
  64. data/lib/action_dispatch/constants.rb +2 -0
  65. data/lib/action_dispatch/deprecator.rb +2 -0
  66. data/lib/action_dispatch/http/cache.rb +27 -26
  67. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  68. data/lib/action_dispatch/http/content_security_policy.rb +44 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +18 -9
  70. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  71. data/lib/action_dispatch/http/headers.rb +22 -22
  72. data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
  73. data/lib/action_dispatch/http/mime_type.rb +31 -24
  74. data/lib/action_dispatch/http/mime_types.rb +2 -0
  75. data/lib/action_dispatch/http/parameters.rb +11 -9
  76. data/lib/action_dispatch/http/permissions_policy.rb +20 -44
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +94 -75
  79. data/lib/action_dispatch/http/response.rb +73 -61
  80. data/lib/action_dispatch/http/upload.rb +18 -16
  81. data/lib/action_dispatch/http/url.rb +75 -73
  82. data/lib/action_dispatch/journey/formatter.rb +13 -6
  83. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  84. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  85. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  86. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  88. data/lib/action_dispatch/journey/parser.rb +4 -3
  89. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  90. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  91. data/lib/action_dispatch/journey/route.rb +9 -7
  92. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  93. data/lib/action_dispatch/journey/router.rb +4 -2
  94. data/lib/action_dispatch/journey/routes.rb +4 -2
  95. data/lib/action_dispatch/journey/scanner.rb +4 -2
  96. data/lib/action_dispatch/journey/visitors.rb +2 -0
  97. data/lib/action_dispatch/journey.rb +2 -0
  98. data/lib/action_dispatch/log_subscriber.rb +2 -0
  99. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  100. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  101. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  102. data/lib/action_dispatch/middleware/cookies.rb +119 -104
  103. data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
  104. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  105. data/lib/action_dispatch/middleware/debug_view.rb +2 -0
  106. data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
  107. data/lib/action_dispatch/middleware/executor.rb +8 -0
  108. data/lib/action_dispatch/middleware/flash.rb +63 -51
  109. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  110. data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
  111. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  112. data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
  113. data/lib/action_dispatch/middleware/request_id.rb +14 -9
  114. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
  120. data/lib/action_dispatch/middleware/ssl.rb +43 -40
  121. data/lib/action_dispatch/middleware/stack.rb +11 -10
  122. data/lib/action_dispatch/middleware/static.rb +33 -31
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
  124. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
  125. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  126. data/lib/action_dispatch/railtie.rb +2 -4
  127. data/lib/action_dispatch/request/session.rb +23 -21
  128. data/lib/action_dispatch/request/utils.rb +2 -0
  129. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  130. data/lib/action_dispatch/routing/inspector.rb +5 -3
  131. data/lib/action_dispatch/routing/mapper.rb +671 -636
  132. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  133. data/lib/action_dispatch/routing/redirection.rb +37 -32
  134. data/lib/action_dispatch/routing/route_set.rb +59 -45
  135. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  136. data/lib/action_dispatch/routing/url_for.rb +130 -125
  137. data/lib/action_dispatch/routing.rb +150 -148
  138. data/lib/action_dispatch/system_test_case.rb +91 -81
  139. data/lib/action_dispatch/system_testing/browser.rb +10 -3
  140. data/lib/action_dispatch/system_testing/driver.rb +3 -1
  141. data/lib/action_dispatch/system_testing/server.rb +2 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  143. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  144. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  145. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  146. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  147. data/lib/action_dispatch/testing/assertions.rb +2 -0
  148. data/lib/action_dispatch/testing/integration.rb +223 -222
  149. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  150. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  151. data/lib/action_dispatch/testing/test_process.rb +12 -8
  152. data/lib/action_dispatch/testing/test_request.rb +3 -1
  153. data/lib/action_dispatch/testing/test_response.rb +27 -26
  154. data/lib/action_dispatch.rb +22 -28
  155. data/lib/action_pack/gem_version.rb +6 -4
  156. data/lib/action_pack/version.rb +3 -1
  157. data/lib/action_pack.rb +17 -16
  158. metadata +39 -16
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/hash/slice"
4
6
  require "active_support/core_ext/enumerable"
5
7
  require "active_support/core_ext/array/extract_options"
@@ -10,10 +12,19 @@ require "action_dispatch/routing/endpoint"
10
12
  module ActionDispatch
11
13
  module Routing
12
14
  class Mapper
15
+ class BacktraceCleaner < ActiveSupport::BacktraceCleaner # :nodoc:
16
+ def initialize
17
+ super
18
+ remove_silencers!
19
+ add_core_silencer
20
+ add_stdlib_silencer
21
+ end
22
+ end
23
+
13
24
  URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port]
14
25
 
15
26
  cattr_accessor :route_source_locations, instance_accessor: false, default: false
16
- cattr_accessor :backtrace_cleaner, instance_accessor: false, default: ActiveSupport::BacktraceCleaner.new
27
+ cattr_accessor :backtrace_cleaner, instance_accessor: false, default: BacktraceCleaner.new
17
28
 
18
29
  class Constraints < Routing::Endpoint # :nodoc:
19
30
  attr_reader :app, :constraints
@@ -22,10 +33,10 @@ module ActionDispatch
22
33
  CALL = ->(app, req) { app.call req.env }
23
34
 
24
35
  def initialize(app, constraints, strategy)
25
- # Unwrap Constraints objects. I don't actually think it's possible
26
- # to pass a Constraints object to this constructor, but there were
27
- # multiple places that kept testing children of this object. I
28
- # *think* they were just being defensive, but I have no idea.
36
+ # Unwrap Constraints objects. I don't actually think it's possible to pass a
37
+ # Constraints object to this constructor, but there were multiple places that
38
+ # kept testing children of this object. I **think** they were just being
39
+ # defensive, but I have no idea.
29
40
  if app.is_a?(self.class)
30
41
  constraints += app.constraints
31
42
  app = app.app
@@ -210,7 +221,7 @@ module ActionDispatch
210
221
  # Add a default constraint for :controller path segments that matches namespaced
211
222
  # controllers with default routes like :controller/:action/:id(.:format), e.g:
212
223
  # GET /admin/products/show/1
213
- # => { controller: 'admin/products', action: 'show', id: '1' }
224
+ # # > { controller: 'admin/products', action: 'show', id: '1' }
214
225
  options[:controller] ||= /.+?/
215
226
  end
216
227
 
@@ -220,12 +231,17 @@ module ActionDispatch
220
231
  if to.nil?
221
232
  controller = default_controller
222
233
  action = default_action
223
- elsif to.is_a?(String) && to.include?("#")
224
- to_endpoint = to.split("#").map!(&:-@)
225
- controller = to_endpoint[0]
226
- action = to_endpoint[1]
234
+ elsif to.is_a?(String)
235
+ if to.include?("#")
236
+ to_endpoint = to.split("#").map!(&:-@)
237
+ controller = to_endpoint[0]
238
+ action = to_endpoint[1]
239
+ else
240
+ controller = default_controller
241
+ action = to
242
+ end
227
243
  else
228
- raise ArgumentError, ":to must respond to `action` or `call`, or it must be a String that includes '#'"
244
+ raise ArgumentError, ":to must respond to `action` or `call`, or it must be a String that includes '#', or the controller should be implicit"
229
245
  end
230
246
 
231
247
  controller = add_controller_module(controller, modyoule)
@@ -359,32 +375,53 @@ module ActionDispatch
359
375
  Routing::RouteSet::Dispatcher.new raise_on_name_error
360
376
  end
361
377
 
362
- def route_source_location
363
- if Mapper.route_source_locations
364
- action_dispatch_dir = File.expand_path("..", __dir__)
365
- caller_location = caller_locations.find { |location| !location.path.include?(action_dispatch_dir) }
366
- cleaned_path = Mapper.backtrace_cleaner.clean([caller_location.path]).first
367
- "#{cleaned_path}:#{caller_location.lineno}" if cleaned_path
378
+ if Thread.respond_to?(:each_caller_location)
379
+ def route_source_location
380
+ if Mapper.route_source_locations
381
+ action_dispatch_dir = File.expand_path("..", __dir__)
382
+ Thread.each_caller_location do |location|
383
+ next if location.path.start_with?(action_dispatch_dir)
384
+
385
+ cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
386
+ next if cleaned_path.nil?
387
+
388
+ return "#{cleaned_path}:#{location.lineno}"
389
+ end
390
+ nil
391
+ end
392
+ end
393
+ else
394
+ def route_source_location
395
+ if Mapper.route_source_locations
396
+ action_dispatch_dir = File.expand_path("..", __dir__)
397
+ caller_locations.each do |location|
398
+ next if location.path.start_with?(action_dispatch_dir)
399
+
400
+ cleaned_path = Mapper.backtrace_cleaner.clean_frame(location.path)
401
+ next if cleaned_path.nil?
402
+
403
+ return "#{cleaned_path}:#{location.lineno}"
404
+ end
405
+ nil
406
+ end
368
407
  end
369
408
  end
370
409
  end
371
410
 
372
- # Invokes Journey::Router::Utils.normalize_path, then ensures that
373
- # /(:locale) becomes (/:locale). Except for root cases, where the
374
- # former is the correct one.
411
+ # Invokes Journey::Router::Utils.normalize_path, then ensures that /(:locale)
412
+ # becomes (/:locale). Except for root cases, where the former is the correct
413
+ # one.
375
414
  def self.normalize_path(path)
376
415
  path = Journey::Router::Utils.normalize_path(path)
377
416
 
378
417
  # the path for a root URL at this point can be something like
379
418
  # "/(/:locale)(/:platform)/(:browser)", and we would want
380
- # "/(:locale)(/:platform)(/:browser)"
381
-
382
- # reverse "/(", "/((" etc to "(/", "((/" etc
419
+ # "/(:locale)(/:platform)(/:browser)" reverse "/(", "/((" etc to "(/", "((/" etc
383
420
  path.gsub!(%r{/(\(+)/?}, '\1/')
384
- # if a path is all optional segments, change the leading "(/" back to
385
- # "/(" so it evaluates to "/" when interpreted with no options.
386
- # Unless, however, at least one secondary segment consists of a static
387
- # part, ex. "(/:locale)(/pages/:page)"
421
+ # if a path is all optional segments, change the leading "(/" back to "/(" so it
422
+ # evaluates to "/" when interpreted with no options. Unless, however, at least
423
+ # one secondary segment consists of a static part, ex.
424
+ # "(/:locale)(/pages/:page)"
388
425
  path.sub!(%r{^(\(+)/}, '/\1') if %r{^(\(+[^)]+\))(\(+/:[^)]+\))*$}.match?(path)
389
426
  path
390
427
  end
@@ -396,206 +433,202 @@ module ActionDispatch
396
433
  module Base
397
434
  # Matches a URL pattern to one or more routes.
398
435
  #
399
- # You should not use the +match+ method in your router
400
- # without specifying an HTTP method.
436
+ # You should not use the `match` method in your router without specifying an
437
+ # HTTP method.
401
438
  #
402
439
  # If you want to expose your action to both GET and POST, use:
403
440
  #
404
- # # sets :controller, :action, and :id in params
405
- # match ':controller/:action/:id', via: [:get, :post]
441
+ # # sets :controller, :action, and :id in params
442
+ # match ':controller/:action/:id', via: [:get, :post]
406
443
  #
407
- # Note that +:controller+, +:action+, and +:id+ are interpreted as URL
408
- # query parameters and thus available through +params+ in an action.
444
+ # Note that `:controller`, `:action`, and `:id` are interpreted as URL query
445
+ # parameters and thus available through `params` in an action.
409
446
  #
410
- # If you want to expose your action to GET, use +get+ in the router:
447
+ # If you want to expose your action to GET, use `get` in the router:
411
448
  #
412
449
  # Instead of:
413
450
  #
414
- # match ":controller/:action/:id"
451
+ # match ":controller/:action/:id"
415
452
  #
416
453
  # Do:
417
454
  #
418
- # get ":controller/:action/:id"
455
+ # get ":controller/:action/:id"
419
456
  #
420
- # Two of these symbols are special, +:controller+ maps to the controller
421
- # and +:action+ to the controller's action. A pattern can also map
422
- # wildcard segments (globs) to params:
457
+ # Two of these symbols are special, `:controller` maps to the controller and
458
+ # `:action` to the controller's action. A pattern can also map wildcard segments
459
+ # (globs) to params:
423
460
  #
424
- # get 'songs/*category/:title', to: 'songs#show'
461
+ # get 'songs/*category/:title', to: 'songs#show'
425
462
  #
426
- # # 'songs/rock/classic/stairway-to-heaven' sets
427
- # # params[:category] = 'rock/classic'
428
- # # params[:title] = 'stairway-to-heaven'
463
+ # # 'songs/rock/classic/stairway-to-heaven' sets
464
+ # # params[:category] = 'rock/classic'
465
+ # # params[:title] = 'stairway-to-heaven'
429
466
  #
430
- # To match a wildcard parameter, it must have a name assigned to it.
431
- # Without a variable name to attach the glob parameter to, the route
432
- # can't be parsed.
467
+ # To match a wildcard parameter, it must have a name assigned to it. Without a
468
+ # variable name to attach the glob parameter to, the route can't be parsed.
433
469
  #
434
- # When a pattern points to an internal route, the route's +:action+ and
435
- # +:controller+ should be set in options or hash shorthand. Examples:
470
+ # When a pattern points to an internal route, the route's `:action` and
471
+ # `:controller` should be set in options or hash shorthand. Examples:
436
472
  #
437
- # match 'photos/:id' => 'photos#show', via: :get
438
- # match 'photos/:id', to: 'photos#show', via: :get
439
- # match 'photos/:id', controller: 'photos', action: 'show', via: :get
473
+ # match 'photos/:id' => 'photos#show', via: :get
474
+ # match 'photos/:id', to: 'photos#show', via: :get
475
+ # match 'photos/:id', controller: 'photos', action: 'show', via: :get
440
476
  #
441
- # A pattern can also point to a +Rack+ endpoint i.e. anything that
442
- # responds to +call+:
477
+ # A pattern can also point to a `Rack` endpoint i.e. anything that responds to
478
+ # `call`:
443
479
  #
444
- # match 'photos/:id', to: -> (hash) { [200, {}, ["Coming soon"]] }, via: :get
445
- # match 'photos/:id', to: PhotoRackApp, via: :get
446
- # # Yes, controller actions are just rack endpoints
447
- # match 'photos/:id', to: PhotosController.action(:show), via: :get
480
+ # match 'photos/:id', to: -> (hash) { [200, {}, ["Coming soon"]] }, via: :get
481
+ # match 'photos/:id', to: PhotoRackApp, via: :get
482
+ # # Yes, controller actions are just rack endpoints
483
+ # match 'photos/:id', to: PhotosController.action(:show), via: :get
448
484
  #
449
485
  # Because requesting various HTTP verbs with a single action has security
450
- # implications, you must either specify the actions in
451
- # the via options or use one of the HttpHelpers[rdoc-ref:HttpHelpers]
452
- # instead +match+
486
+ # implications, you must either specify the actions in the via options or use
487
+ # one of the [HttpHelpers](rdoc-ref:HttpHelpers) instead `match`
453
488
  #
454
- # === Options
489
+ # ### Options
455
490
  #
456
491
  # Any options not seen here are passed on as params with the URL.
457
492
  #
458
- # [:controller]
459
- # The route's controller.
493
+ # :controller
494
+ # : The route's controller.
460
495
  #
461
- # [:action]
462
- # The route's action.
496
+ # :action
497
+ # : The route's action.
463
498
  #
464
- # [:param]
465
- # Overrides the default resource identifier +:id+ (name of the
466
- # dynamic segment used to generate the routes).
467
- # You can access that segment from your controller using
468
- # <tt>params[<:param>]</tt>.
469
- # In your router:
499
+ # :param
500
+ # : Overrides the default resource identifier `:id` (name of the dynamic
501
+ # segment used to generate the routes). You can access that segment from
502
+ # your controller using `params[<:param>]`. In your router:
470
503
  #
471
- # resources :users, param: :name
504
+ # resources :users, param: :name
472
505
  #
473
- # The +users+ resource here will have the following routes generated for it:
506
+ # The `users` resource here will have the following routes generated for it:
474
507
  #
475
- # GET /users(.:format)
476
- # POST /users(.:format)
477
- # GET /users/new(.:format)
478
- # GET /users/:name/edit(.:format)
479
- # GET /users/:name(.:format)
480
- # PATCH/PUT /users/:name(.:format)
481
- # DELETE /users/:name(.:format)
508
+ # GET /users(.:format)
509
+ # POST /users(.:format)
510
+ # GET /users/new(.:format)
511
+ # GET /users/:name/edit(.:format)
512
+ # GET /users/:name(.:format)
513
+ # PATCH/PUT /users/:name(.:format)
514
+ # DELETE /users/:name(.:format)
482
515
  #
483
- # You can override <tt>ActiveRecord::Base#to_param</tt> of a related
484
- # model to construct a URL:
516
+ # You can override `ActiveRecord::Base#to_param` of a related model to
517
+ # construct a URL:
485
518
  #
486
- # class User < ActiveRecord::Base
487
- # def to_param
488
- # name
489
- # end
490
- # end
519
+ # class User < ActiveRecord::Base
520
+ # def to_param
521
+ # name
522
+ # end
523
+ # end
491
524
  #
492
- # user = User.find_by(name: 'Phusion')
493
- # user_path(user) # => "/users/Phusion"
525
+ # user = User.find_by(name: 'Phusion')
526
+ # user_path(user) # => "/users/Phusion"
494
527
  #
495
- # [:path]
496
- # The path prefix for the routes.
528
+ # :path
529
+ # : The path prefix for the routes.
497
530
  #
498
- # [:module]
499
- # The namespace for :controller.
531
+ # :module
532
+ # : The namespace for :controller.
500
533
  #
501
- # match 'path', to: 'c#a', module: 'sekret', controller: 'posts', via: :get
502
- # # => Sekret::PostsController
534
+ # match 'path', to: 'c#a', module: 'sekret', controller: 'posts', via: :get
535
+ # # => Sekret::PostsController
503
536
  #
504
- # See <tt>Scoping#namespace</tt> for its scope equivalent.
537
+ # See `Scoping#namespace` for its scope equivalent.
505
538
  #
506
- # [:as]
507
- # The name used to generate routing helpers.
539
+ # :as
540
+ # : The name used to generate routing helpers.
508
541
  #
509
- # [:via]
510
- # Allowed HTTP verb(s) for route.
542
+ # :via
543
+ # : Allowed HTTP verb(s) for route.
511
544
  #
512
- # match 'path', to: 'c#a', via: :get
513
- # match 'path', to: 'c#a', via: [:get, :post]
514
- # match 'path', to: 'c#a', via: :all
545
+ # match 'path', to: 'c#a', via: :get
546
+ # match 'path', to: 'c#a', via: [:get, :post]
547
+ # match 'path', to: 'c#a', via: :all
515
548
  #
516
- # [:to]
517
- # Points to a +Rack+ endpoint. Can be an object that responds to
518
- # +call+ or a string representing a controller's action.
549
+ # :to
550
+ # : Points to a `Rack` endpoint. Can be an object that responds to `call` or a
551
+ # string representing a controller's action.
519
552
  #
520
- # match 'path', to: 'controller#action', via: :get
521
- # match 'path', to: -> (env) { [200, {}, ["Success!"]] }, via: :get
522
- # match 'path', to: RackApp, via: :get
553
+ # match 'path', to: 'controller#action', via: :get
554
+ # match 'path', to: -> (env) { [200, {}, ["Success!"]] }, via: :get
555
+ # match 'path', to: RackApp, via: :get
523
556
  #
524
- # [:on]
525
- # Shorthand for wrapping routes in a specific RESTful context. Valid
526
- # values are +:member+, +:collection+, and +:new+. Only use within
527
- # <tt>resource(s)</tt> block. For example:
557
+ # :on
558
+ # : Shorthand for wrapping routes in a specific RESTful context. Valid values
559
+ # are `:member`, `:collection`, and `:new`. Only use within `resource(s)`
560
+ # block. For example:
528
561
  #
529
- # resource :bar do
530
- # match 'foo', to: 'c#a', on: :member, via: [:get, :post]
531
- # end
562
+ # resource :bar do
563
+ # match 'foo', to: 'c#a', on: :member, via: [:get, :post]
564
+ # end
532
565
  #
533
- # Is equivalent to:
566
+ # Is equivalent to:
534
567
  #
535
- # resource :bar do
536
- # member do
537
- # match 'foo', to: 'c#a', via: [:get, :post]
538
- # end
539
- # end
568
+ # resource :bar do
569
+ # member do
570
+ # match 'foo', to: 'c#a', via: [:get, :post]
571
+ # end
572
+ # end
540
573
  #
541
- # [:constraints]
542
- # Constrains parameters with a hash of regular expressions
543
- # or an object that responds to <tt>matches?</tt>. In addition, constraints
544
- # other than path can also be specified with any object
545
- # that responds to <tt>===</tt> (e.g. String, Array, Range, etc.).
574
+ # :constraints
575
+ # : Constrains parameters with a hash of regular expressions or an object that
576
+ # responds to `matches?`. In addition, constraints other than path can also
577
+ # be specified with any object that responds to `===` (e.g. String, Array,
578
+ # Range, etc.).
546
579
  #
547
- # match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: :get
580
+ # match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: :get
548
581
  #
549
- # match 'json_only', constraints: { format: 'json' }, via: :get
582
+ # match 'json_only', constraints: { format: 'json' }, via: :get
550
583
  #
551
- # class PermitList
552
- # def matches?(request) request.remote_ip == '1.2.3.4' end
553
- # end
554
- # match 'path', to: 'c#a', constraints: PermitList.new, via: :get
584
+ # class PermitList
585
+ # def matches?(request) request.remote_ip == '1.2.3.4' end
586
+ # end
587
+ # match 'path', to: 'c#a', constraints: PermitList.new, via: :get
555
588
  #
556
- # See <tt>Scoping#constraints</tt> for more examples with its scope
557
- # equivalent.
589
+ # See `Scoping#constraints` for more examples with its scope equivalent.
558
590
  #
559
- # [:defaults]
560
- # Sets defaults for parameters
591
+ # :defaults
592
+ # : Sets defaults for parameters
561
593
  #
562
- # # Sets params[:format] to 'jpg' by default
563
- # match 'path', to: 'c#a', defaults: { format: 'jpg' }, via: :get
594
+ # # Sets params[:format] to 'jpg' by default
595
+ # match 'path', to: 'c#a', defaults: { format: 'jpg' }, via: :get
564
596
  #
565
- # See <tt>Scoping#defaults</tt> for its scope equivalent.
597
+ # See `Scoping#defaults` for its scope equivalent.
566
598
  #
567
- # [:anchor]
568
- # Boolean to anchor a <tt>match</tt> pattern. Default is true. When set to
569
- # false, the pattern matches any request prefixed with the given path.
599
+ # :anchor
600
+ # : Boolean to anchor a `match` pattern. Default is true. When set to false,
601
+ # the pattern matches any request prefixed with the given path.
570
602
  #
571
- # # Matches any request starting with 'path'
572
- # match 'path', to: 'c#a', anchor: false, via: :get
603
+ # # Matches any request starting with 'path'
604
+ # match 'path', to: 'c#a', anchor: false, via: :get
605
+ #
606
+ # :format
607
+ # : Allows you to specify the default value for optional `format` segment or
608
+ # disable it by supplying `false`.
573
609
  #
574
- # [:format]
575
- # Allows you to specify the default value for optional +format+
576
- # segment or disable it by supplying +false+.
577
610
  def match(path, options = nil)
578
611
  end
579
612
 
580
613
  # Mount a Rack-based application to be used within the application.
581
614
  #
582
- # mount SomeRackApp, at: "some_route"
615
+ # mount SomeRackApp, at: "some_route"
583
616
  #
584
617
  # Alternatively:
585
618
  #
586
- # mount(SomeRackApp => "some_route")
619
+ # mount(SomeRackApp => "some_route")
587
620
  #
588
- # For options, see +match+, as +mount+ uses it internally.
621
+ # For options, see `match`, as `mount` uses it internally.
589
622
  #
590
- # All mounted applications come with routing helpers to access them.
591
- # These are named after the class specified, so for the above example
592
- # the helper is either +some_rack_app_path+ or +some_rack_app_url+.
593
- # To customize this helper's name, use the +:as+ option:
623
+ # All mounted applications come with routing helpers to access them. These are
624
+ # named after the class specified, so for the above example the helper is either
625
+ # `some_rack_app_path` or `some_rack_app_url`. To customize this helper's name,
626
+ # use the `:as` option:
594
627
  #
595
- # mount(SomeRackApp => "some_route", as: "exciting")
628
+ # mount(SomeRackApp => "some_route", as: "exciting")
596
629
  #
597
- # This will generate the +exciting_path+ and +exciting_url+ helpers
598
- # which can be used to navigate to this mounted app.
630
+ # This will generate the `exciting_path` and `exciting_url` helpers which can be
631
+ # used to navigate to this mounted app.
599
632
  def mount(app, options = nil)
600
633
  if options
601
634
  path = options.delete(:at)
@@ -669,7 +702,8 @@ module ActionDispatch
669
702
  prefix_options.reverse_merge!(options[:_recall].slice(*_route.segment_keys))
670
703
  end
671
704
 
672
- # We must actually delete prefix segment keys to avoid passing them to next url_for.
705
+ # We must actually delete prefix segment keys to avoid passing them to next
706
+ # url_for.
673
707
  _route.segment_keys.each { |k| options.delete(k) }
674
708
  _url_helpers.public_send("#{name}_path", prefix_options)
675
709
  end
@@ -680,7 +714,7 @@ module ActionDispatch
680
714
  def optimize_routes_generation?; false; end
681
715
 
682
716
  define_method :find_script_name do |options|
683
- if options.key? :script_name
717
+ if options.key?(:script_name) && options[:script_name].present?
684
718
  super(options)
685
719
  else
686
720
  script_namer.call(options)
@@ -691,50 +725,50 @@ module ActionDispatch
691
725
  end
692
726
 
693
727
  module HttpHelpers
694
- # Define a route that only recognizes HTTP GET.
695
- # For supported arguments, see match[rdoc-ref:Base#match]
728
+ # Define a route that only recognizes HTTP GET. For supported arguments, see
729
+ # [match](rdoc-ref:Base#match)
696
730
  #
697
- # get 'bacon', to: 'food#bacon'
731
+ # get 'bacon', to: 'food#bacon'
698
732
  def get(*args, &block)
699
733
  map_method(:get, args, &block)
700
734
  end
701
735
 
702
- # Define a route that only recognizes HTTP POST.
703
- # For supported arguments, see match[rdoc-ref:Base#match]
736
+ # Define a route that only recognizes HTTP POST. For supported arguments, see
737
+ # [match](rdoc-ref:Base#match)
704
738
  #
705
- # post 'bacon', to: 'food#bacon'
739
+ # post 'bacon', to: 'food#bacon'
706
740
  def post(*args, &block)
707
741
  map_method(:post, args, &block)
708
742
  end
709
743
 
710
- # Define a route that only recognizes HTTP PATCH.
711
- # For supported arguments, see match[rdoc-ref:Base#match]
744
+ # Define a route that only recognizes HTTP PATCH. For supported arguments, see
745
+ # [match](rdoc-ref:Base#match)
712
746
  #
713
- # patch 'bacon', to: 'food#bacon'
747
+ # patch 'bacon', to: 'food#bacon'
714
748
  def patch(*args, &block)
715
749
  map_method(:patch, args, &block)
716
750
  end
717
751
 
718
- # Define a route that only recognizes HTTP PUT.
719
- # For supported arguments, see match[rdoc-ref:Base#match]
752
+ # Define a route that only recognizes HTTP PUT. For supported arguments, see
753
+ # [match](rdoc-ref:Base#match)
720
754
  #
721
- # put 'bacon', to: 'food#bacon'
755
+ # put 'bacon', to: 'food#bacon'
722
756
  def put(*args, &block)
723
757
  map_method(:put, args, &block)
724
758
  end
725
759
 
726
- # Define a route that only recognizes HTTP DELETE.
727
- # For supported arguments, see match[rdoc-ref:Base#match]
760
+ # Define a route that only recognizes HTTP DELETE. For supported arguments, see
761
+ # [match](rdoc-ref:Base#match)
728
762
  #
729
- # delete 'broccoli', to: 'food#broccoli'
763
+ # delete 'broccoli', to: 'food#broccoli'
730
764
  def delete(*args, &block)
731
765
  map_method(:delete, args, &block)
732
766
  end
733
767
 
734
- # Define a route that only recognizes HTTP OPTIONS.
735
- # For supported arguments, see match[rdoc-ref:Base#match]
768
+ # Define a route that only recognizes HTTP OPTIONS. For supported arguments, see
769
+ # [match](rdoc-ref:Base#match)
736
770
  #
737
- # options 'carrots', to: 'food#carrots'
771
+ # options 'carrots', to: 'food#carrots'
738
772
  def options(*args, &block)
739
773
  map_method(:options, args, &block)
740
774
  end
@@ -748,91 +782,90 @@ module ActionDispatch
748
782
  end
749
783
  end
750
784
 
751
- # You may wish to organize groups of controllers under a namespace.
752
- # Most commonly, you might group a number of administrative controllers
753
- # under an +admin+ namespace. You would place these controllers under
754
- # the <tt>app/controllers/admin</tt> directory, and you can group them
755
- # together in your router:
785
+ # You may wish to organize groups of controllers under a namespace. Most
786
+ # commonly, you might group a number of administrative controllers under an
787
+ # `admin` namespace. You would place these controllers under the
788
+ # `app/controllers/admin` directory, and you can group them together in your
789
+ # router:
756
790
  #
757
- # namespace "admin" do
758
- # resources :posts, :comments
759
- # end
791
+ # namespace "admin" do
792
+ # resources :posts, :comments
793
+ # end
760
794
  #
761
795
  # This will create a number of routes for each of the posts and comments
762
- # controller. For +Admin::PostsController+, \Rails will create:
796
+ # controller. For `Admin::PostsController`, Rails will create:
763
797
  #
764
- # GET /admin/posts
765
- # GET /admin/posts/new
766
- # POST /admin/posts
767
- # GET /admin/posts/1
768
- # GET /admin/posts/1/edit
769
- # PATCH/PUT /admin/posts/1
770
- # DELETE /admin/posts/1
798
+ # GET /admin/posts
799
+ # GET /admin/posts/new
800
+ # POST /admin/posts
801
+ # GET /admin/posts/1
802
+ # GET /admin/posts/1/edit
803
+ # PATCH/PUT /admin/posts/1
804
+ # DELETE /admin/posts/1
771
805
  #
772
806
  # If you want to route /posts (without the prefix /admin) to
773
- # +Admin::PostsController+, you could use
807
+ # `Admin::PostsController`, you could use
774
808
  #
775
- # scope module: "admin" do
776
- # resources :posts
777
- # end
809
+ # scope module: "admin" do
810
+ # resources :posts
811
+ # end
778
812
  #
779
813
  # or, for a single case
780
814
  #
781
- # resources :posts, module: "admin"
815
+ # resources :posts, module: "admin"
782
816
  #
783
- # If you want to route /admin/posts to +PostsController+
784
- # (without the <tt>Admin::</tt> module prefix), you could use
817
+ # If you want to route /admin/posts to `PostsController` (without the `Admin::`
818
+ # module prefix), you could use
785
819
  #
786
- # scope "/admin" do
787
- # resources :posts
788
- # end
820
+ # scope "/admin" do
821
+ # resources :posts
822
+ # end
789
823
  #
790
824
  # or, for a single case
791
825
  #
792
- # resources :posts, path: "/admin/posts"
826
+ # resources :posts, path: "/admin/posts"
793
827
  #
794
- # In each of these cases, the named routes remain the same as if you did
795
- # not use scope. In the last case, the following paths map to
796
- # +PostsController+:
828
+ # In each of these cases, the named routes remain the same as if you did not use
829
+ # scope. In the last case, the following paths map to `PostsController`:
797
830
  #
798
- # GET /admin/posts
799
- # GET /admin/posts/new
800
- # POST /admin/posts
801
- # GET /admin/posts/1
802
- # GET /admin/posts/1/edit
803
- # PATCH/PUT /admin/posts/1
804
- # DELETE /admin/posts/1
831
+ # GET /admin/posts
832
+ # GET /admin/posts/new
833
+ # POST /admin/posts
834
+ # GET /admin/posts/1
835
+ # GET /admin/posts/1/edit
836
+ # PATCH/PUT /admin/posts/1
837
+ # DELETE /admin/posts/1
805
838
  module Scoping
806
839
  # Scopes a set of routes to the given default options.
807
840
  #
808
841
  # Take the following route definition as an example:
809
842
  #
810
- # scope path: ":account_id", as: "account" do
811
- # resources :projects
812
- # end
843
+ # scope path: ":account_id", as: "account" do
844
+ # resources :projects
845
+ # end
813
846
  #
814
- # This generates helpers such as +account_projects_path+, just like +resources+ does.
815
- # The difference here being that the routes generated are like /:account_id/projects,
816
- # rather than /accounts/:account_id/projects.
847
+ # This generates helpers such as `account_projects_path`, just like `resources`
848
+ # does. The difference here being that the routes generated are like
849
+ # /:account_id/projects, rather than /accounts/:account_id/projects.
817
850
  #
818
- # === Options
851
+ # ### Options
819
852
  #
820
- # Takes same options as <tt>Base#match</tt> and <tt>Resources#resources</tt>.
853
+ # Takes same options as `Base#match` and `Resources#resources`.
821
854
  #
822
- # # route /posts (without the prefix /admin) to +Admin::PostsController+
823
- # scope module: "admin" do
824
- # resources :posts
825
- # end
855
+ # # route /posts (without the prefix /admin) to +Admin::PostsController+
856
+ # scope module: "admin" do
857
+ # resources :posts
858
+ # end
826
859
  #
827
- # # prefix the posts resource's requests with '/admin'
828
- # scope path: "/admin" do
829
- # resources :posts
830
- # end
860
+ # # prefix the posts resource's requests with '/admin'
861
+ # scope path: "/admin" do
862
+ # resources :posts
863
+ # end
831
864
  #
832
- # # prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
833
- # scope as: "sekret" do
834
- # resources :posts
835
- # end
865
+ # # prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
866
+ # scope as: "sekret" do
867
+ # resources :posts
868
+ # end
836
869
  def scope(*args)
837
870
  options = args.extract_options!.dup
838
871
  scope = {}
@@ -889,9 +922,9 @@ module ActionDispatch
889
922
 
890
923
  # Scopes routes to a specific controller
891
924
  #
892
- # controller "food" do
893
- # match "bacon", action: :bacon, via: :get
894
- # end
925
+ # controller "food" do
926
+ # match "bacon", action: :bacon, via: :get
927
+ # end
895
928
  def controller(controller)
896
929
  @scope = @scope.new(controller: controller)
897
930
  yield
@@ -901,42 +934,42 @@ module ActionDispatch
901
934
 
902
935
  # Scopes routes to a specific namespace. For example:
903
936
  #
904
- # namespace :admin do
905
- # resources :posts
906
- # end
937
+ # namespace :admin do
938
+ # resources :posts
939
+ # end
907
940
  #
908
941
  # This generates the following routes:
909
942
  #
910
- # admin_posts GET /admin/posts(.:format) admin/posts#index
911
- # admin_posts POST /admin/posts(.:format) admin/posts#create
912
- # new_admin_post GET /admin/posts/new(.:format) admin/posts#new
913
- # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit
914
- # admin_post GET /admin/posts/:id(.:format) admin/posts#show
915
- # admin_post PATCH/PUT /admin/posts/:id(.:format) admin/posts#update
916
- # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy
943
+ # admin_posts GET /admin/posts(.:format) admin/posts#index
944
+ # admin_posts POST /admin/posts(.:format) admin/posts#create
945
+ # new_admin_post GET /admin/posts/new(.:format) admin/posts#new
946
+ # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit
947
+ # admin_post GET /admin/posts/:id(.:format) admin/posts#show
948
+ # admin_post PATCH/PUT /admin/posts/:id(.:format) admin/posts#update
949
+ # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy
917
950
  #
918
- # === Options
951
+ # ### Options
919
952
  #
920
- # The +:path+, +:as+, +:module+, +:shallow_path+, and +:shallow_prefix+
921
- # options all default to the name of the namespace.
953
+ # The `:path`, `:as`, `:module`, `:shallow_path`, and `:shallow_prefix` options
954
+ # all default to the name of the namespace.
922
955
  #
923
- # For options, see <tt>Base#match</tt>. For +:shallow_path+ option, see
924
- # <tt>Resources#resources</tt>.
956
+ # For options, see `Base#match`. For `:shallow_path` option, see
957
+ # `Resources#resources`.
925
958
  #
926
- # # accessible through /sekret/posts rather than /admin/posts
927
- # namespace :admin, path: "sekret" do
928
- # resources :posts
929
- # end
959
+ # # accessible through /sekret/posts rather than /admin/posts
960
+ # namespace :admin, path: "sekret" do
961
+ # resources :posts
962
+ # end
930
963
  #
931
- # # maps to +Sekret::PostsController+ rather than +Admin::PostsController+
932
- # namespace :admin, module: "sekret" do
933
- # resources :posts
934
- # end
964
+ # # maps to +Sekret::PostsController+ rather than +Admin::PostsController+
965
+ # namespace :admin, module: "sekret" do
966
+ # resources :posts
967
+ # end
935
968
  #
936
- # # generates +sekret_posts_path+ rather than +admin_posts_path+
937
- # namespace :admin, as: "sekret" do
938
- # resources :posts
939
- # end
969
+ # # generates +sekret_posts_path+ rather than +admin_posts_path+
970
+ # namespace :admin, as: "sekret" do
971
+ # resources :posts
972
+ # end
940
973
  def namespace(path, options = {}, &block)
941
974
  path = path.to_s
942
975
 
@@ -952,70 +985,74 @@ module ActionDispatch
952
985
  end
953
986
  end
954
987
 
955
- # === Parameter Restriction
956
- # Allows you to constrain the nested routes based on a set of rules.
957
- # For instance, in order to change the routes to allow for a dot character in the +id+ parameter:
988
+ # ### Parameter Restriction
989
+ # Allows you to constrain the nested routes based on a set of rules. For
990
+ # instance, in order to change the routes to allow for a dot character in the
991
+ # `id` parameter:
958
992
  #
959
- # constraints(id: /\d+\.\d+/) do
960
- # resources :posts
961
- # end
993
+ # constraints(id: /\d+\.\d+/) do
994
+ # resources :posts
995
+ # end
962
996
  #
963
- # Now routes such as +/posts/1+ will no longer be valid, but +/posts/1.1+ will be.
964
- # The +id+ parameter must match the constraint passed in for this example.
997
+ # Now routes such as `/posts/1` will no longer be valid, but `/posts/1.1` will
998
+ # be. The `id` parameter must match the constraint passed in for this example.
965
999
  #
966
1000
  # You may use this to also restrict other parameters:
967
1001
  #
968
- # resources :posts do
969
- # constraints(post_id: /\d+\.\d+/) do
970
- # resources :comments
1002
+ # resources :posts do
1003
+ # constraints(post_id: /\d+\.\d+/) do
1004
+ # resources :comments
1005
+ # end
971
1006
  # end
972
- # end
973
1007
  #
974
- # === Restricting based on IP
1008
+ # ### Restricting based on IP
975
1009
  #
976
1010
  # Routes can also be constrained to an IP or a certain range of IP addresses:
977
1011
  #
978
- # constraints(ip: /192\.168\.\d+\.\d+/) do
979
- # resources :posts
980
- # end
1012
+ # constraints(ip: /192\.168\.\d+\.\d+/) do
1013
+ # resources :posts
1014
+ # end
981
1015
  #
982
- # Any user connecting from the 192.168.* range will be able to see this resource,
983
- # where as any user connecting outside of this range will be told there is no such route.
1016
+ # Any user connecting from the 192.168.* range will be able to see this
1017
+ # resource, where as any user connecting outside of this range will be told
1018
+ # there is no such route.
984
1019
  #
985
- # === Dynamic request matching
1020
+ # ### Dynamic request matching
986
1021
  #
987
1022
  # Requests to routes can be constrained based on specific criteria:
988
1023
  #
989
- # constraints(-> (req) { /iPhone/.match?(req.env["HTTP_USER_AGENT"]) }) do
990
- # resources :iphones
991
- # end
1024
+ # constraints(-> (req) { /iPhone/.match?(req.env["HTTP_USER_AGENT"]) }) do
1025
+ # resources :iphones
1026
+ # end
992
1027
  #
993
- # You are able to move this logic out into a class if it is too complex for routes.
994
- # This class must have a +matches?+ method defined on it which either returns +true+
995
- # if the user should be given access to that route, or +false+ if the user should not.
1028
+ # You are able to move this logic out into a class if it is too complex for
1029
+ # routes. This class must have a `matches?` method defined on it which either
1030
+ # returns `true` if the user should be given access to that route, or `false` if
1031
+ # the user should not.
996
1032
  #
997
- # class Iphone
998
- # def self.matches?(request)
999
- # /iPhone/.match?(request.env["HTTP_USER_AGENT"])
1000
- # end
1001
- # end
1033
+ # class Iphone
1034
+ # def self.matches?(request)
1035
+ # /iPhone/.match?(request.env["HTTP_USER_AGENT"])
1036
+ # end
1037
+ # end
1002
1038
  #
1003
- # An expected place for this code would be +lib/constraints+.
1039
+ # An expected place for this code would be `lib/constraints`.
1004
1040
  #
1005
1041
  # This class is then used like this:
1006
1042
  #
1007
- # constraints(Iphone) do
1008
- # resources :iphones
1009
- # end
1043
+ # constraints(Iphone) do
1044
+ # resources :iphones
1045
+ # end
1010
1046
  def constraints(constraints = {}, &block)
1011
1047
  scope(constraints: constraints, &block)
1012
1048
  end
1013
1049
 
1014
1050
  # Allows you to set default parameters for a route, such as this:
1015
- # defaults id: 'home' do
1016
- # match 'scoped_pages/(:id)', to: 'pages#show'
1017
- # end
1018
- # Using this, the +:id+ parameter here will default to 'home'.
1051
+ # defaults id: 'home' do
1052
+ # match 'scoped_pages/(:id)', to: 'pages#show'
1053
+ # end
1054
+ #
1055
+ # Using this, the `:id` parameter here will default to 'home'.
1019
1056
  def defaults(defaults = {})
1020
1057
  @scope = @scope.new(defaults: merge_defaults_scope(@scope[:defaults], defaults))
1021
1058
  yield
@@ -1091,48 +1128,46 @@ module ActionDispatch
1091
1128
  end
1092
1129
  end
1093
1130
 
1094
- # Resource routing allows you to quickly declare all of the common routes
1095
- # for a given resourceful controller. Instead of declaring separate routes
1096
- # for your +index+, +show+, +new+, +edit+, +create+, +update+, and +destroy+
1097
- # actions, a resourceful route declares them in a single line of code:
1131
+ # Resource routing allows you to quickly declare all of the common routes for a
1132
+ # given resourceful controller. Instead of declaring separate routes for your
1133
+ # `index`, `show`, `new`, `edit`, `create`, `update`, and `destroy` actions, a
1134
+ # resourceful route declares them in a single line of code:
1098
1135
  #
1099
- # resources :photos
1136
+ # resources :photos
1100
1137
  #
1101
- # Sometimes, you have a resource that clients always look up without
1102
- # referencing an ID. A common example, /profile always shows the profile of
1103
- # the currently logged in user. In this case, you can use a singular resource
1104
- # to map /profile (rather than /profile/:id) to the show action.
1138
+ # Sometimes, you have a resource that clients always look up without referencing
1139
+ # an ID. A common example, /profile always shows the profile of the currently
1140
+ # logged in user. In this case, you can use a singular resource to map /profile
1141
+ # (rather than /profile/:id) to the show action.
1105
1142
  #
1106
- # resource :profile
1143
+ # resource :profile
1107
1144
  #
1108
- # It's common to have resources that are logically children of other
1109
- # resources:
1145
+ # It's common to have resources that are logically children of other resources:
1110
1146
  #
1111
- # resources :magazines do
1112
- # resources :ads
1113
- # end
1147
+ # resources :magazines do
1148
+ # resources :ads
1149
+ # end
1114
1150
  #
1115
1151
  # You may wish to organize groups of controllers under a namespace. Most
1116
- # commonly, you might group a number of administrative controllers under
1117
- # an +admin+ namespace. You would place these controllers under the
1118
- # <tt>app/controllers/admin</tt> directory, and you can group them together
1119
- # in your router:
1120
- #
1121
- # namespace "admin" do
1122
- # resources :posts, :comments
1123
- # end
1152
+ # commonly, you might group a number of administrative controllers under an
1153
+ # `admin` namespace. You would place these controllers under the
1154
+ # `app/controllers/admin` directory, and you can group them together in your
1155
+ # router:
1124
1156
  #
1125
- # By default the +:id+ parameter doesn't accept dots. If you need to
1126
- # use dots as part of the +:id+ parameter add a constraint which
1127
- # overrides this restriction, e.g:
1157
+ # namespace "admin" do
1158
+ # resources :posts, :comments
1159
+ # end
1128
1160
  #
1129
- # resources :articles, id: /[^\/]+/
1161
+ # By default the `:id` parameter doesn't accept dots. If you need to use dots as
1162
+ # part of the `:id` parameter add a constraint which overrides this restriction,
1163
+ # e.g:
1130
1164
  #
1131
- # This allows any character other than a slash as part of your +:id+.
1165
+ # resources :articles, id: /[^\/]+/
1132
1166
  #
1167
+ # This allows any character other than a slash as part of your `:id`.
1133
1168
  module Resources
1134
- # CANONICAL_ACTIONS holds all actions that does not need a prefix or
1135
- # a path appended since they fit properly in their scope level.
1169
+ # CANONICAL_ACTIONS holds all actions that does not need a prefix or a path
1170
+ # appended since they fit properly in their scope level.
1136
1171
  VALID_ON_OPTIONS = [:new, :collection, :member]
1137
1172
  RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param, :concerns]
1138
1173
  CANONICAL_ACTIONS = %w(index create new show update destroy)
@@ -1195,8 +1230,8 @@ module ActionDispatch
1195
1230
 
1196
1231
  alias :member_name :singular
1197
1232
 
1198
- # Checks for uncountable plurals, and appends "_index" if the plural
1199
- # and singular form are the same.
1233
+ # Checks for uncountable plurals, and appends "_index" if the plural and
1234
+ # singular form are the same.
1200
1235
  def collection_name
1201
1236
  singular == plural ? "#{plural}_index" : plural
1202
1237
  end
@@ -1269,37 +1304,35 @@ module ActionDispatch
1269
1304
  @scope[:path_names].merge!(options)
1270
1305
  end
1271
1306
 
1272
- # Sometimes, you have a resource that clients always look up without
1273
- # referencing an ID. A common example, /profile always shows the
1274
- # profile of the currently logged in user. In this case, you can use
1275
- # a singular resource to map /profile (rather than /profile/:id) to
1276
- # the show action:
1307
+ # Sometimes, you have a resource that clients always look up without referencing
1308
+ # an ID. A common example, /profile always shows the profile of the currently
1309
+ # logged in user. In this case, you can use a singular resource to map /profile
1310
+ # (rather than /profile/:id) to the show action:
1277
1311
  #
1278
- # resource :profile
1312
+ # resource :profile
1279
1313
  #
1280
- # This creates six different routes in your application, all mapping to
1281
- # the +Profiles+ controller (note that the controller is named after
1282
- # the plural):
1314
+ # This creates six different routes in your application, all mapping to the
1315
+ # `Profiles` controller (note that the controller is named after the plural):
1283
1316
  #
1284
- # GET /profile/new
1285
- # GET /profile
1286
- # GET /profile/edit
1287
- # PATCH/PUT /profile
1288
- # DELETE /profile
1289
- # POST /profile
1317
+ # GET /profile/new
1318
+ # GET /profile
1319
+ # GET /profile/edit
1320
+ # PATCH/PUT /profile
1321
+ # DELETE /profile
1322
+ # POST /profile
1290
1323
  #
1291
- # If you want instances of a model to work with this resource via
1292
- # record identification (e.g. in +form_with+ or +redirect_to+), you
1293
- # will need to call resolve[rdoc-ref:CustomUrls#resolve]:
1324
+ # If you want instances of a model to work with this resource via record
1325
+ # identification (e.g. in `form_with` or `redirect_to`), you will need to call
1326
+ # [resolve](rdoc-ref:CustomUrls#resolve):
1294
1327
  #
1295
- # resource :profile
1296
- # resolve('Profile') { [:profile] }
1328
+ # resource :profile
1329
+ # resolve('Profile') { [:profile] }
1297
1330
  #
1298
- # # Enables this to work with singular routes:
1299
- # form_with(model: @profile) {}
1331
+ # # Enables this to work with singular routes:
1332
+ # form_with(model: @profile) {}
1300
1333
  #
1301
- # === Options
1302
- # Takes same options as resources[rdoc-ref:#resources]
1334
+ # ### Options
1335
+ # Takes same options as [resources](rdoc-ref:#resources)
1303
1336
  def resource(*resources, &block)
1304
1337
  options = resources.extract_options!.dup
1305
1338
 
@@ -1329,143 +1362,147 @@ module ActionDispatch
1329
1362
  self
1330
1363
  end
1331
1364
 
1332
- # In \Rails, a resourceful route provides a mapping between HTTP verbs
1333
- # and URLs and controller actions. By convention, each action also maps
1334
- # to particular CRUD operations in a database. A single entry in the
1335
- # routing file, such as
1365
+ # In Rails, a resourceful route provides a mapping between HTTP verbs and URLs
1366
+ # and controller actions. By convention, each action also maps to particular
1367
+ # CRUD operations in a database. A single entry in the routing file, such as
1336
1368
  #
1337
- # resources :photos
1369
+ # resources :photos
1338
1370
  #
1339
- # creates seven different routes in your application, all mapping to
1340
- # the +Photos+ controller:
1371
+ # creates seven different routes in your application, all mapping to the
1372
+ # `Photos` controller:
1341
1373
  #
1342
- # GET /photos
1343
- # GET /photos/new
1344
- # POST /photos
1345
- # GET /photos/:id
1346
- # GET /photos/:id/edit
1347
- # PATCH/PUT /photos/:id
1348
- # DELETE /photos/:id
1374
+ # GET /photos
1375
+ # GET /photos/new
1376
+ # POST /photos
1377
+ # GET /photos/:id
1378
+ # GET /photos/:id/edit
1379
+ # PATCH/PUT /photos/:id
1380
+ # DELETE /photos/:id
1349
1381
  #
1350
1382
  # Resources can also be nested infinitely by using this block syntax:
1351
1383
  #
1352
- # resources :photos do
1353
- # resources :comments
1354
- # end
1384
+ # resources :photos do
1385
+ # resources :comments
1386
+ # end
1355
1387
  #
1356
1388
  # This generates the following comments routes:
1357
1389
  #
1358
- # GET /photos/:photo_id/comments
1359
- # GET /photos/:photo_id/comments/new
1360
- # POST /photos/:photo_id/comments
1361
- # GET /photos/:photo_id/comments/:id
1362
- # GET /photos/:photo_id/comments/:id/edit
1363
- # PATCH/PUT /photos/:photo_id/comments/:id
1364
- # DELETE /photos/:photo_id/comments/:id
1390
+ # GET /photos/:photo_id/comments
1391
+ # GET /photos/:photo_id/comments/new
1392
+ # POST /photos/:photo_id/comments
1393
+ # GET /photos/:photo_id/comments/:id
1394
+ # GET /photos/:photo_id/comments/:id/edit
1395
+ # PATCH/PUT /photos/:photo_id/comments/:id
1396
+ # DELETE /photos/:photo_id/comments/:id
1365
1397
  #
1366
- # === Options
1367
- # Takes same options as match[rdoc-ref:Base#match] as well as:
1398
+ # ### Options
1399
+ # Takes same options as [match](rdoc-ref:Base#match) as well as:
1368
1400
  #
1369
- # [:path_names]
1370
- # Allows you to change the segment component of the +edit+ and +new+ actions.
1371
- # Actions not specified are not changed.
1401
+ # :path_names
1402
+ # : Allows you to change the segment component of the `edit` and `new`
1403
+ # actions. Actions not specified are not changed.
1372
1404
  #
1373
- # resources :posts, path_names: { new: "brand_new" }
1405
+ # resources :posts, path_names: { new: "brand_new" }
1374
1406
  #
1375
- # The above example will now change /posts/new to /posts/brand_new.
1407
+ # The above example will now change /posts/new to /posts/brand_new.
1376
1408
  #
1377
- # [:path]
1378
- # Allows you to change the path prefix for the resource.
1409
+ # :path
1410
+ # : Allows you to change the path prefix for the resource.
1379
1411
  #
1380
- # resources :posts, path: 'postings'
1412
+ # resources :posts, path: 'postings'
1381
1413
  #
1382
- # The resource and all segments will now route to /postings instead of /posts.
1414
+ # The resource and all segments will now route to /postings instead of
1415
+ # /posts.
1383
1416
  #
1384
- # [:only]
1385
- # Only generate routes for the given actions.
1417
+ # :only
1418
+ # : Only generate routes for the given actions.
1386
1419
  #
1387
- # resources :cows, only: :show
1388
- # resources :cows, only: [:show, :index]
1420
+ # resources :cows, only: :show
1421
+ # resources :cows, only: [:show, :index]
1389
1422
  #
1390
- # [:except]
1391
- # Generate all routes except for the given actions.
1423
+ # :except
1424
+ # : Generate all routes except for the given actions.
1392
1425
  #
1393
- # resources :cows, except: :show
1394
- # resources :cows, except: [:show, :index]
1426
+ # resources :cows, except: :show
1427
+ # resources :cows, except: [:show, :index]
1395
1428
  #
1396
- # [:shallow]
1397
- # Generates shallow routes for nested resource(s). When placed on a parent resource,
1398
- # generates shallow routes for all nested resources.
1429
+ # :shallow
1430
+ # : Generates shallow routes for nested resource(s). When placed on a parent
1431
+ # resource, generates shallow routes for all nested resources.
1399
1432
  #
1400
- # resources :posts, shallow: true do
1401
- # resources :comments
1402
- # end
1433
+ # resources :posts, shallow: true do
1434
+ # resources :comments
1435
+ # end
1403
1436
  #
1404
- # Is the same as:
1437
+ # Is the same as:
1405
1438
  #
1406
- # resources :posts do
1407
- # resources :comments, except: [:show, :edit, :update, :destroy]
1408
- # end
1409
- # resources :comments, only: [:show, :edit, :update, :destroy]
1439
+ # resources :posts do
1440
+ # resources :comments, except: [:show, :edit, :update, :destroy]
1441
+ # end
1442
+ # resources :comments, only: [:show, :edit, :update, :destroy]
1410
1443
  #
1411
- # This allows URLs for resources that otherwise would be deeply nested such
1412
- # as a comment on a blog post like <tt>/posts/a-long-permalink/comments/1234</tt>
1413
- # to be shortened to just <tt>/comments/1234</tt>.
1444
+ # This allows URLs for resources that otherwise would be deeply nested such
1445
+ # as a comment on a blog post like `/posts/a-long-permalink/comments/1234`
1446
+ # to be shortened to just `/comments/1234`.
1414
1447
  #
1415
- # Set <tt>shallow: false</tt> on a child resource to ignore a parent's shallow parameter.
1448
+ # Set `shallow: false` on a child resource to ignore a parent's shallow
1449
+ # parameter.
1416
1450
  #
1417
- # [:shallow_path]
1418
- # Prefixes nested shallow routes with the specified path.
1451
+ # :shallow_path
1452
+ # : Prefixes nested shallow routes with the specified path.
1419
1453
  #
1420
- # scope shallow_path: "sekret" do
1421
- # resources :posts do
1422
- # resources :comments, shallow: true
1423
- # end
1424
- # end
1454
+ # scope shallow_path: "sekret" do
1455
+ # resources :posts do
1456
+ # resources :comments, shallow: true
1457
+ # end
1458
+ # end
1425
1459
  #
1426
- # The +comments+ resource here will have the following routes generated for it:
1460
+ # The `comments` resource here will have the following routes generated for
1461
+ # it:
1427
1462
  #
1428
- # post_comments GET /posts/:post_id/comments(.:format)
1429
- # post_comments POST /posts/:post_id/comments(.:format)
1430
- # new_post_comment GET /posts/:post_id/comments/new(.:format)
1431
- # edit_comment GET /sekret/comments/:id/edit(.:format)
1432
- # comment GET /sekret/comments/:id(.:format)
1433
- # comment PATCH/PUT /sekret/comments/:id(.:format)
1434
- # comment DELETE /sekret/comments/:id(.:format)
1463
+ # post_comments GET /posts/:post_id/comments(.:format)
1464
+ # post_comments POST /posts/:post_id/comments(.:format)
1465
+ # new_post_comment GET /posts/:post_id/comments/new(.:format)
1466
+ # edit_comment GET /sekret/comments/:id/edit(.:format)
1467
+ # comment GET /sekret/comments/:id(.:format)
1468
+ # comment PATCH/PUT /sekret/comments/:id(.:format)
1469
+ # comment DELETE /sekret/comments/:id(.:format)
1435
1470
  #
1436
- # [:shallow_prefix]
1437
- # Prefixes nested shallow route names with specified prefix.
1471
+ # :shallow_prefix
1472
+ # : Prefixes nested shallow route names with specified prefix.
1438
1473
  #
1439
- # scope shallow_prefix: "sekret" do
1440
- # resources :posts do
1441
- # resources :comments, shallow: true
1442
- # end
1443
- # end
1474
+ # scope shallow_prefix: "sekret" do
1475
+ # resources :posts do
1476
+ # resources :comments, shallow: true
1477
+ # end
1478
+ # end
1479
+ #
1480
+ # The `comments` resource here will have the following routes generated for
1481
+ # it:
1444
1482
  #
1445
- # The +comments+ resource here will have the following routes generated for it:
1483
+ # post_comments GET /posts/:post_id/comments(.:format)
1484
+ # post_comments POST /posts/:post_id/comments(.:format)
1485
+ # new_post_comment GET /posts/:post_id/comments/new(.:format)
1486
+ # edit_sekret_comment GET /comments/:id/edit(.:format)
1487
+ # sekret_comment GET /comments/:id(.:format)
1488
+ # sekret_comment PATCH/PUT /comments/:id(.:format)
1489
+ # sekret_comment DELETE /comments/:id(.:format)
1446
1490
  #
1447
- # post_comments GET /posts/:post_id/comments(.:format)
1448
- # post_comments POST /posts/:post_id/comments(.:format)
1449
- # new_post_comment GET /posts/:post_id/comments/new(.:format)
1450
- # edit_sekret_comment GET /comments/:id/edit(.:format)
1451
- # sekret_comment GET /comments/:id(.:format)
1452
- # sekret_comment PATCH/PUT /comments/:id(.:format)
1453
- # sekret_comment DELETE /comments/:id(.:format)
1491
+ # :format
1492
+ # : Allows you to specify the default value for optional `format` segment or
1493
+ # disable it by supplying `false`.
1454
1494
  #
1455
- # [:format]
1456
- # Allows you to specify the default value for optional +format+
1457
- # segment or disable it by supplying +false+.
1495
+ # :param
1496
+ # : Allows you to override the default param name of `:id` in the URL.
1458
1497
  #
1459
- # [:param]
1460
- # Allows you to override the default param name of +:id+ in the URL.
1461
1498
  #
1462
- # === Examples
1499
+ # ### Examples
1463
1500
  #
1464
- # # routes call +Admin::PostsController+
1465
- # resources :posts, module: "admin"
1501
+ # # routes call +Admin::PostsController+
1502
+ # resources :posts, module: "admin"
1466
1503
  #
1467
- # # resource actions are at /admin/posts.
1468
- # resources :posts, path: "admin/posts"
1504
+ # # resource actions are at /admin/posts.
1505
+ # resources :posts, path: "admin/posts"
1469
1506
  def resources(*resources, &block)
1470
1507
  options = resources.extract_options!.dup
1471
1508
 
@@ -1498,16 +1535,15 @@ module ActionDispatch
1498
1535
 
1499
1536
  # To add a route to the collection:
1500
1537
  #
1501
- # resources :photos do
1502
- # collection do
1503
- # get 'search'
1538
+ # resources :photos do
1539
+ # collection do
1540
+ # get 'search'
1541
+ # end
1504
1542
  # end
1505
- # end
1506
1543
  #
1507
- # This will enable \Rails to recognize paths such as <tt>/photos/search</tt>
1508
- # with GET, and route to the search action of +PhotosController+. It will also
1509
- # create the <tt>search_photos_url</tt> and <tt>search_photos_path</tt>
1510
- # route helpers.
1544
+ # This will enable Rails to recognize paths such as `/photos/search` with GET,
1545
+ # and route to the search action of `PhotosController`. It will also create the
1546
+ # `search_photos_url` and `search_photos_path` route helpers.
1511
1547
  def collection(&block)
1512
1548
  unless resource_scope?
1513
1549
  raise ArgumentError, "can't use collection outside resource(s) scope"
@@ -1520,15 +1556,15 @@ module ActionDispatch
1520
1556
 
1521
1557
  # To add a member route, add a member block into the resource block:
1522
1558
  #
1523
- # resources :photos do
1524
- # member do
1525
- # get 'preview'
1559
+ # resources :photos do
1560
+ # member do
1561
+ # get 'preview'
1562
+ # end
1526
1563
  # end
1527
- # end
1528
1564
  #
1529
- # This will recognize <tt>/photos/1/preview</tt> with GET, and route to the
1530
- # preview action of +PhotosController+. It will also create the
1531
- # <tt>preview_photo_url</tt> and <tt>preview_photo_path</tt> helpers.
1565
+ # This will recognize `/photos/1/preview` with GET, and route to the preview
1566
+ # action of `PhotosController`. It will also create the `preview_photo_url` and
1567
+ # `preview_photo_path` helpers.
1532
1568
  def member(&block)
1533
1569
  unless resource_scope?
1534
1570
  raise ArgumentError, "can't use member outside resource(s) scope"
@@ -1595,29 +1631,28 @@ module ActionDispatch
1595
1631
  !parent_resource.singleton? && @scope[:shallow]
1596
1632
  end
1597
1633
 
1598
- # Loads another routes file with the given +name+ located inside the
1599
- # +config/routes+ directory. In that file, you can use the normal
1600
- # routing DSL, but <i>do not</i> surround it with a
1601
- # +Rails.application.routes.draw+ block.
1602
- #
1603
- # # config/routes.rb
1604
- # Rails.application.routes.draw do
1605
- # draw :admin # Loads `config/routes/admin.rb`
1606
- # draw "third_party/some_gem" # Loads `config/routes/third_party/some_gem.rb`
1607
- # end
1608
- #
1609
- # # config/routes/admin.rb
1610
- # namespace :admin do
1611
- # resources :accounts
1612
- # end
1613
- #
1614
- # # config/routes/third_party/some_gem.rb
1615
- # mount SomeGem::Engine, at: "/some_gem"
1616
- #
1617
- # <b>CAUTION:</b> Use this feature with care. Having multiple routes
1618
- # files can negatively impact discoverability and readability. For most
1619
- # applications — even those with a few hundred routes — it's easier for
1620
- # developers to have a single routes file.
1634
+ # Loads another routes file with the given `name` located inside the
1635
+ # `config/routes` directory. In that file, you can use the normal routing DSL,
1636
+ # but *do not* surround it with a `Rails.application.routes.draw` block.
1637
+ #
1638
+ # # config/routes.rb
1639
+ # Rails.application.routes.draw do
1640
+ # draw :admin # Loads `config/routes/admin.rb`
1641
+ # draw "third_party/some_gem" # Loads `config/routes/third_party/some_gem.rb`
1642
+ # end
1643
+ #
1644
+ # # config/routes/admin.rb
1645
+ # namespace :admin do
1646
+ # resources :accounts
1647
+ # end
1648
+ #
1649
+ # # config/routes/third_party/some_gem.rb
1650
+ # mount SomeGem::Engine, at: "/some_gem"
1651
+ #
1652
+ # **CAUTION:** Use this feature with care. Having multiple routes files can
1653
+ # negatively impact discoverability and readability. For most applications —
1654
+ # even those with a few hundred routes it's easier for developers to have a
1655
+ # single routes file.
1621
1656
  def draw(name)
1622
1657
  path = @draw_paths.find do |_path|
1623
1658
  File.exist? "#{_path}/#{name}.rb"
@@ -1634,12 +1669,12 @@ module ActionDispatch
1634
1669
  instance_eval(File.read(route_path), route_path.to_s)
1635
1670
  end
1636
1671
 
1637
- # Matches a URL pattern to one or more routes.
1638
- # For more information, see match[rdoc-ref:Base#match].
1672
+ # Matches a URL pattern to one or more routes. For more information, see
1673
+ # [match](rdoc-ref:Base#match).
1639
1674
  #
1640
- # match 'path' => 'controller#action', via: :patch
1641
- # match 'path', to: 'controller#action', via: :post
1642
- # match 'path', 'otherpath', on: :member, via: :get
1675
+ # match 'path' => 'controller#action', via: :patch
1676
+ # match 'path', to: 'controller#action', via: :post
1677
+ # match 'path', 'otherpath', on: :member, via: :get
1643
1678
  def match(path, *rest, &block)
1644
1679
  if rest.empty? && Hash === path
1645
1680
  options = path
@@ -1674,19 +1709,19 @@ module ActionDispatch
1674
1709
  end
1675
1710
  end
1676
1711
 
1677
- # You can specify what \Rails should route "/" to with the root method:
1712
+ # You can specify what Rails should route "/" to with the root method:
1678
1713
  #
1679
- # root to: 'pages#main'
1714
+ # root to: 'pages#main'
1680
1715
  #
1681
- # For options, see +match+, as +root+ uses it internally.
1716
+ # For options, see `match`, as `root` uses it internally.
1682
1717
  #
1683
1718
  # You can also pass a string which will expand
1684
1719
  #
1685
- # root 'pages#main'
1720
+ # root 'pages#main'
1686
1721
  #
1687
- # You should put the root route at the top of <tt>config/routes.rb</tt>,
1688
- # because this means it will be matched first. As this is the most popular route
1689
- # of most \Rails applications, this is beneficial.
1722
+ # You should put the root route at the top of `config/routes.rb`, because this
1723
+ # means it will be matched first. As this is the most popular route of most
1724
+ # Rails applications, this is beneficial.
1690
1725
  def root(path, options = {})
1691
1726
  if path.is_a?(String)
1692
1727
  options[:to] = path
@@ -1864,9 +1899,9 @@ module ActionDispatch
1864
1899
  candidate = action_name.select(&:present?).join("_")
1865
1900
 
1866
1901
  unless candidate.empty?
1867
- # If a name was not explicitly given, we check if it is valid
1868
- # and return nil in case it isn't. Otherwise, we pass the invalid name
1869
- # forward so the underlying router engine treats it and raises an exception.
1902
+ # If a name was not explicitly given, we check if it is valid and return nil in
1903
+ # case it isn't. Otherwise, we pass the invalid name forward so the underlying
1904
+ # router engine treats it and raises an exception.
1870
1905
  if as.nil?
1871
1906
  candidate unless !candidate.match?(/\A[_a-z]/i) || has_named_route?(candidate)
1872
1907
  else
@@ -2002,83 +2037,81 @@ module ActionDispatch
2002
2037
  end
2003
2038
  end
2004
2039
 
2005
- # Routing Concerns allow you to declare common routes that can be reused
2006
- # inside others resources and routes.
2040
+ # Routing Concerns allow you to declare common routes that can be reused inside
2041
+ # others resources and routes.
2007
2042
  #
2008
- # concern :commentable do
2009
- # resources :comments
2010
- # end
2043
+ # concern :commentable do
2044
+ # resources :comments
2045
+ # end
2011
2046
  #
2012
- # concern :image_attachable do
2013
- # resources :images, only: :index
2014
- # end
2047
+ # concern :image_attachable do
2048
+ # resources :images, only: :index
2049
+ # end
2015
2050
  #
2016
2051
  # These concerns are used in Resources routing:
2017
2052
  #
2018
- # resources :messages, concerns: [:commentable, :image_attachable]
2053
+ # resources :messages, concerns: [:commentable, :image_attachable]
2019
2054
  #
2020
2055
  # or in a scope or namespace:
2021
2056
  #
2022
- # namespace :posts do
2023
- # concerns :commentable
2024
- # end
2057
+ # namespace :posts do
2058
+ # concerns :commentable
2059
+ # end
2025
2060
  module Concerns
2026
2061
  # Define a routing concern using a name.
2027
2062
  #
2028
- # Concerns may be defined inline, using a block, or handled by
2029
- # another object, by passing that object as the second parameter.
2063
+ # Concerns may be defined inline, using a block, or handled by another object,
2064
+ # by passing that object as the second parameter.
2030
2065
  #
2031
- # The concern object, if supplied, should respond to <tt>call</tt>,
2032
- # which will receive two parameters:
2066
+ # The concern object, if supplied, should respond to `call`, which will receive
2067
+ # two parameters:
2033
2068
  #
2034
- # * The current mapper
2035
- # * A hash of options which the concern object may use
2069
+ # * The current mapper
2070
+ # * A hash of options which the concern object may use
2036
2071
  #
2037
- # Options may also be used by concerns defined in a block by accepting
2038
- # a block parameter. So, using a block, you might do something as
2039
- # simple as limit the actions available on certain resources, passing
2040
- # standard resource options through the concern:
2072
+ # Options may also be used by concerns defined in a block by accepting a block
2073
+ # parameter. So, using a block, you might do something as simple as limit the
2074
+ # actions available on certain resources, passing standard resource options
2075
+ # through the concern:
2041
2076
  #
2042
- # concern :commentable do |options|
2043
- # resources :comments, options
2044
- # end
2077
+ # concern :commentable do |options|
2078
+ # resources :comments, options
2079
+ # end
2045
2080
  #
2046
- # resources :posts, concerns: :commentable
2047
- # resources :archived_posts do
2048
- # # Don't allow comments on archived posts
2049
- # concerns :commentable, only: [:index, :show]
2050
- # end
2081
+ # resources :posts, concerns: :commentable
2082
+ # resources :archived_posts do
2083
+ # # Don't allow comments on archived posts
2084
+ # concerns :commentable, only: [:index, :show]
2085
+ # end
2051
2086
  #
2052
- # Or, using a callable object, you might implement something more
2053
- # specific to your application, which would be out of place in your
2054
- # routes file.
2087
+ # Or, using a callable object, you might implement something more specific to
2088
+ # your application, which would be out of place in your routes file.
2055
2089
  #
2056
- # # purchasable.rb
2057
- # class Purchasable
2058
- # def initialize(defaults = {})
2059
- # @defaults = defaults
2060
- # end
2090
+ # # purchasable.rb
2091
+ # class Purchasable
2092
+ # def initialize(defaults = {})
2093
+ # @defaults = defaults
2094
+ # end
2061
2095
  #
2062
- # def call(mapper, options = {})
2063
- # options = @defaults.merge(options)
2064
- # mapper.resources :purchases
2065
- # mapper.resources :receipts
2066
- # mapper.resources :returns if options[:returnable]
2096
+ # def call(mapper, options = {})
2097
+ # options = @defaults.merge(options)
2098
+ # mapper.resources :purchases
2099
+ # mapper.resources :receipts
2100
+ # mapper.resources :returns if options[:returnable]
2101
+ # end
2067
2102
  # end
2068
- # end
2069
2103
  #
2070
- # # routes.rb
2071
- # concern :purchasable, Purchasable.new(returnable: true)
2104
+ # # routes.rb
2105
+ # concern :purchasable, Purchasable.new(returnable: true)
2072
2106
  #
2073
- # resources :toys, concerns: :purchasable
2074
- # resources :electronics, concerns: :purchasable
2075
- # resources :pets do
2076
- # concerns :purchasable, returnable: false
2077
- # end
2107
+ # resources :toys, concerns: :purchasable
2108
+ # resources :electronics, concerns: :purchasable
2109
+ # resources :pets do
2110
+ # concerns :purchasable, returnable: false
2111
+ # end
2078
2112
  #
2079
- # Any routing helpers can be used inside a concern. If using a
2080
- # callable, they're accessible from the Mapper that's passed to
2081
- # <tt>call</tt>.
2113
+ # Any routing helpers can be used inside a concern. If using a callable, they're
2114
+ # accessible from the Mapper that's passed to `call`.
2082
2115
  def concern(name, callable = nil, &block)
2083
2116
  callable ||= lambda { |mapper, options| mapper.instance_exec(options, &block) }
2084
2117
  @concerns[name] = callable
@@ -2086,15 +2119,15 @@ module ActionDispatch
2086
2119
 
2087
2120
  # Use the named concerns
2088
2121
  #
2089
- # resources :posts do
2090
- # concerns :commentable
2091
- # end
2122
+ # resources :posts do
2123
+ # concerns :commentable
2124
+ # end
2092
2125
  #
2093
2126
  # Concerns also work in any routes helper that you want to use:
2094
2127
  #
2095
- # namespace :posts do
2096
- # concerns :commentable
2097
- # end
2128
+ # namespace :posts do
2129
+ # concerns :commentable
2130
+ # end
2098
2131
  def concerns(*args)
2099
2132
  options = args.extract_options!
2100
2133
  args.flatten.each do |name|
@@ -2108,53 +2141,55 @@ module ActionDispatch
2108
2141
  end
2109
2142
 
2110
2143
  module CustomUrls
2111
- # Define custom URL helpers that will be added to the application's
2112
- # routes. This allows you to override and/or replace the default behavior
2113
- # of routing helpers, e.g:
2144
+ # Define custom URL helpers that will be added to the application's routes. This
2145
+ # allows you to override and/or replace the default behavior of routing helpers,
2146
+ # e.g:
2114
2147
  #
2115
- # direct :homepage do
2116
- # "https://rubyonrails.org"
2117
- # end
2148
+ # direct :homepage do
2149
+ # "https://rubyonrails.org"
2150
+ # end
2118
2151
  #
2119
- # direct :commentable do |model|
2120
- # [ model, anchor: model.dom_id ]
2121
- # end
2152
+ # direct :commentable do |model|
2153
+ # [ model, anchor: model.dom_id ]
2154
+ # end
2122
2155
  #
2123
- # direct :main do
2124
- # { controller: "pages", action: "index", subdomain: "www" }
2125
- # end
2156
+ # direct :main do
2157
+ # { controller: "pages", action: "index", subdomain: "www" }
2158
+ # end
2126
2159
  #
2127
- # The return value from the block passed to +direct+ must be a valid set of
2128
- # arguments for +url_for+ which will actually build the URL string. This can
2129
- # be one of the following:
2160
+ # The return value from the block passed to `direct` must be a valid set of
2161
+ # arguments for `url_for` which will actually build the URL string. This can be
2162
+ # one of the following:
2130
2163
  #
2131
- # * A string, which is treated as a generated URL
2132
- # * A hash, e.g. <tt>{ controller: "pages", action: "index" }</tt>
2133
- # * An array, which is passed to +polymorphic_url+
2134
- # * An Active Model instance
2135
- # * An Active Model class
2164
+ # * A string, which is treated as a generated URL
2165
+ # * A hash, e.g. `{ controller: "pages", action: "index" }`
2166
+ # * An array, which is passed to `polymorphic_url`
2167
+ # * An Active Model instance
2168
+ # * An Active Model class
2136
2169
  #
2137
- # NOTE: Other URL helpers can be called in the block but be careful not to invoke
2138
- # your custom URL helper again otherwise it will result in a stack overflow error.
2139
2170
  #
2140
- # You can also specify default options that will be passed through to
2141
- # your URL helper definition, e.g:
2171
+ # NOTE: Other URL helpers can be called in the block but be careful not to
2172
+ # invoke your custom URL helper again otherwise it will result in a stack
2173
+ # overflow error.
2142
2174
  #
2143
- # direct :browse, page: 1, size: 10 do |options|
2144
- # [ :products, options.merge(params.permit(:page, :size).to_h.symbolize_keys) ]
2145
- # end
2175
+ # You can also specify default options that will be passed through to your URL
2176
+ # helper definition, e.g:
2146
2177
  #
2147
- # In this instance the +params+ object comes from the context in which the
2148
- # block is executed, e.g. generating a URL inside a controller action or a view.
2149
- # If the block is executed where there isn't a +params+ object such as this:
2178
+ # direct :browse, page: 1, size: 10 do |options|
2179
+ # [ :products, options.merge(params.permit(:page, :size).to_h.symbolize_keys) ]
2180
+ # end
2150
2181
  #
2151
- # Rails.application.routes.url_helpers.browse_path
2182
+ # In this instance the `params` object comes from the context in which the block
2183
+ # is executed, e.g. generating a URL inside a controller action or a view. If
2184
+ # the block is executed where there isn't a `params` object such as this:
2152
2185
  #
2153
- # then it will raise a +NameError+. Because of this you need to be aware of the
2186
+ # Rails.application.routes.url_helpers.browse_path
2187
+ #
2188
+ # then it will raise a `NameError`. Because of this you need to be aware of the
2154
2189
  # context in which you will use your custom URL helper when defining it.
2155
2190
  #
2156
- # NOTE: The +direct+ method can't be used inside of a scope block such as
2157
- # +namespace+ or +scope+ and will raise an error if it detects that it is.
2191
+ # NOTE: The `direct` method can't be used inside of a scope block such as
2192
+ # `namespace` or `scope` and will raise an error if it detects that it is.
2158
2193
  def direct(name, options = {}, &block)
2159
2194
  unless @scope.root?
2160
2195
  raise RuntimeError, "The direct method can't be used inside a routes scope block"
@@ -2163,50 +2198,50 @@ module ActionDispatch
2163
2198
  @set.add_url_helper(name, options, &block)
2164
2199
  end
2165
2200
 
2166
- # Define custom polymorphic mappings of models to URLs. This alters the
2167
- # behavior of +polymorphic_url+ and consequently the behavior of
2168
- # +link_to+ and +form_for+ when passed a model instance, e.g:
2201
+ # Define custom polymorphic mappings of models to URLs. This alters the behavior
2202
+ # of `polymorphic_url` and consequently the behavior of `link_to` and `form_for`
2203
+ # when passed a model instance, e.g:
2169
2204
  #
2170
- # resource :basket
2205
+ # resource :basket
2171
2206
  #
2172
- # resolve "Basket" do
2173
- # [:basket]
2174
- # end
2207
+ # resolve "Basket" do
2208
+ # [:basket]
2209
+ # end
2175
2210
  #
2176
- # This will now generate "/basket" when a +Basket+ instance is passed to
2177
- # +link_to+ or +form_for+ instead of the standard "/baskets/:id".
2211
+ # This will now generate "/basket" when a `Basket` instance is passed to
2212
+ # `link_to` or `form_for` instead of the standard "/baskets/:id".
2178
2213
  #
2179
- # NOTE: This custom behavior only applies to simple polymorphic URLs where
2180
- # a single model instance is passed and not more complicated forms, e.g:
2214
+ # NOTE: This custom behavior only applies to simple polymorphic URLs where a
2215
+ # single model instance is passed and not more complicated forms, e.g:
2181
2216
  #
2182
- # # config/routes.rb
2183
- # resource :profile
2184
- # namespace :admin do
2185
- # resources :users
2186
- # end
2217
+ # # config/routes.rb
2218
+ # resource :profile
2219
+ # namespace :admin do
2220
+ # resources :users
2221
+ # end
2187
2222
  #
2188
- # resolve("User") { [:profile] }
2223
+ # resolve("User") { [:profile] }
2189
2224
  #
2190
- # # app/views/application/_menu.html.erb
2191
- # link_to "Profile", @current_user
2192
- # link_to "Profile", [:admin, @current_user]
2225
+ # # app/views/application/_menu.html.erb
2226
+ # link_to "Profile", @current_user
2227
+ # link_to "Profile", [:admin, @current_user]
2193
2228
  #
2194
- # The first +link_to+ will generate "/profile" but the second will generate
2195
- # the standard polymorphic URL of "/admin/users/1".
2229
+ # The first `link_to` will generate "/profile" but the second will generate the
2230
+ # standard polymorphic URL of "/admin/users/1".
2196
2231
  #
2197
- # You can pass options to a polymorphic mapping - the arity for the block
2198
- # needs to be two as the instance is passed as the first argument, e.g:
2232
+ # You can pass options to a polymorphic mapping - the arity for the block needs
2233
+ # to be two as the instance is passed as the first argument, e.g:
2199
2234
  #
2200
- # resolve "Basket", anchor: "items" do |basket, options|
2201
- # [:basket, options]
2202
- # end
2235
+ # resolve "Basket", anchor: "items" do |basket, options|
2236
+ # [:basket, options]
2237
+ # end
2203
2238
  #
2204
- # This generates the URL "/basket#items" because when the last item in an
2205
- # array passed to +polymorphic_url+ is a hash then it's treated as options
2206
- # to the URL helper that gets called.
2239
+ # This generates the URL "/basket#items" because when the last item in an array
2240
+ # passed to `polymorphic_url` is a hash then it's treated as options to the URL
2241
+ # helper that gets called.
2207
2242
  #
2208
- # NOTE: The +resolve+ method can't be used inside of a scope block such as
2209
- # +namespace+ or +scope+ and will raise an error if it detects that it is.
2243
+ # NOTE: The `resolve` method can't be used inside of a scope block such as
2244
+ # `namespace` or `scope` and will raise an error if it detects that it is.
2210
2245
  def resolve(*args, &block)
2211
2246
  unless @scope.root?
2212
2247
  raise RuntimeError, "The resolve method can't be used inside a routes scope block"