actionpack 5.2.4.rc1 → 6.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +179 -335
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -2
  5. data/lib/abstract_controller/base.rb +4 -2
  6. data/lib/abstract_controller/caching/fragments.rb +6 -22
  7. data/lib/abstract_controller/callbacks.rb +12 -0
  8. data/lib/abstract_controller/collector.rb +1 -1
  9. data/lib/abstract_controller/helpers.rb +2 -2
  10. data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
  11. data/lib/abstract_controller/translation.rb +1 -0
  12. data/lib/action_controller.rb +1 -0
  13. data/lib/action_controller/api.rb +2 -1
  14. data/lib/action_controller/base.rb +2 -7
  15. data/lib/action_controller/caching.rb +1 -1
  16. data/lib/action_controller/log_subscriber.rb +8 -5
  17. data/lib/action_controller/metal.rb +1 -1
  18. data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
  19. data/lib/action_controller/metal/conditional_get.rb +9 -3
  20. data/lib/action_controller/metal/data_streaming.rb +5 -6
  21. data/lib/action_controller/metal/default_headers.rb +17 -0
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  23. data/lib/action_controller/metal/exceptions.rb +22 -1
  24. data/lib/action_controller/metal/flash.rb +5 -5
  25. data/lib/action_controller/metal/force_ssl.rb +15 -56
  26. data/lib/action_controller/metal/head.rb +1 -1
  27. data/lib/action_controller/metal/helpers.rb +3 -4
  28. data/lib/action_controller/metal/http_authentication.rb +20 -21
  29. data/lib/action_controller/metal/implicit_render.rb +4 -14
  30. data/lib/action_controller/metal/instrumentation.rb +3 -5
  31. data/lib/action_controller/metal/live.rb +29 -27
  32. data/lib/action_controller/metal/mime_responds.rb +13 -2
  33. data/lib/action_controller/metal/params_wrapper.rb +17 -13
  34. data/lib/action_controller/metal/redirecting.rb +5 -5
  35. data/lib/action_controller/metal/renderers.rb +1 -1
  36. data/lib/action_controller/metal/rendering.rb +2 -2
  37. data/lib/action_controller/metal/request_forgery_protection.rb +23 -12
  38. data/lib/action_controller/metal/strong_parameters.rb +63 -44
  39. data/lib/action_controller/metal/url_for.rb +1 -1
  40. data/lib/action_controller/railties/helpers.rb +1 -1
  41. data/lib/action_controller/renderer.rb +16 -3
  42. data/lib/action_controller/template_assertions.rb +1 -1
  43. data/lib/action_controller/test_case.rb +3 -7
  44. data/lib/action_dispatch.rb +4 -1
  45. data/lib/action_dispatch/http/cache.rb +14 -10
  46. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  47. data/lib/action_dispatch/http/content_security_policy.rb +28 -16
  48. data/lib/action_dispatch/http/filter_parameters.rb +8 -6
  49. data/lib/action_dispatch/http/filter_redirect.rb +1 -1
  50. data/lib/action_dispatch/http/headers.rb +1 -1
  51. data/lib/action_dispatch/http/mime_negotiation.rb +7 -5
  52. data/lib/action_dispatch/http/mime_type.rb +14 -6
  53. data/lib/action_dispatch/http/parameter_filter.rb +5 -79
  54. data/lib/action_dispatch/http/parameters.rb +13 -3
  55. data/lib/action_dispatch/http/request.rb +10 -13
  56. data/lib/action_dispatch/http/response.rb +33 -19
  57. data/lib/action_dispatch/http/upload.rb +9 -1
  58. data/lib/action_dispatch/http/url.rb +81 -81
  59. data/lib/action_dispatch/journey/formatter.rb +2 -2
  60. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
  61. data/lib/action_dispatch/journey/nodes/node.rb +9 -8
  62. data/lib/action_dispatch/journey/path/pattern.rb +6 -2
  63. data/lib/action_dispatch/journey/route.rb +5 -4
  64. data/lib/action_dispatch/journey/router.rb +0 -3
  65. data/lib/action_dispatch/journey/router/utils.rb +10 -10
  66. data/lib/action_dispatch/journey/routes.rb +0 -1
  67. data/lib/action_dispatch/journey/scanner.rb +11 -4
  68. data/lib/action_dispatch/journey/visitors.rb +1 -1
  69. data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
  70. data/lib/action_dispatch/middleware/callbacks.rb +2 -4
  71. data/lib/action_dispatch/middleware/cookies.rb +46 -72
  72. data/lib/action_dispatch/middleware/debug_exceptions.rb +39 -59
  73. data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
  74. data/lib/action_dispatch/middleware/debug_view.rb +68 -0
  75. data/lib/action_dispatch/middleware/exception_wrapper.rb +49 -15
  76. data/lib/action_dispatch/middleware/flash.rb +1 -1
  77. data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
  78. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -2
  79. data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
  80. data/lib/action_dispatch/middleware/request_id.rb +2 -2
  81. data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -6
  82. data/lib/action_dispatch/middleware/show_exceptions.rb +1 -1
  83. data/lib/action_dispatch/middleware/ssl.rb +8 -8
  84. data/lib/action_dispatch/middleware/stack.rb +33 -1
  85. data/lib/action_dispatch/middleware/static.rb +5 -6
  86. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  87. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  88. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
  89. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  90. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
  91. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  92. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
  95. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  96. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +7 -4
  97. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +4 -2
  98. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -0
  99. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  101. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  102. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  103. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
  104. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
  105. data/lib/action_dispatch/railtie.rb +3 -0
  106. data/lib/action_dispatch/request/session.rb +8 -0
  107. data/lib/action_dispatch/routing.rb +21 -20
  108. data/lib/action_dispatch/routing/inspector.rb +99 -50
  109. data/lib/action_dispatch/routing/mapper.rb +60 -38
  110. data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -4
  111. data/lib/action_dispatch/routing/route_set.rb +24 -27
  112. data/lib/action_dispatch/routing/url_for.rb +1 -0
  113. data/lib/action_dispatch/system_test_case.rb +23 -2
  114. data/lib/action_dispatch/system_testing/browser.rb +38 -7
  115. data/lib/action_dispatch/system_testing/driver.rb +10 -1
  116. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -5
  117. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +7 -5
  118. data/lib/action_dispatch/testing/assertions.rb +1 -1
  119. data/lib/action_dispatch/testing/assertions/response.rb +2 -3
  120. data/lib/action_dispatch/testing/assertions/routing.rb +15 -3
  121. data/lib/action_dispatch/testing/integration.rb +12 -5
  122. data/lib/action_dispatch/testing/request_encoder.rb +2 -2
  123. data/lib/action_dispatch/testing/test_process.rb +2 -2
  124. data/lib/action_dispatch/testing/test_response.rb +4 -32
  125. data/lib/action_pack.rb +1 -1
  126. data/lib/action_pack/gem_version.rb +4 -4
  127. metadata +24 -13
@@ -4,8 +4,10 @@
4
4
  <% end %>
5
5
 
6
6
  <%= @exception.message %>
7
- <% if %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}.match?(@exception.message) %>
8
- To resolve this issue run: bin/rails active_storage:install
7
+ <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
8
+ To resolve this issue run: rails active_storage:install
9
+ <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
10
+ To resolve this issue run: rails action_mailbox:install
9
11
  <% end %>
10
12
 
11
13
  <%= render template: "rescues/_source" %>
@@ -117,6 +117,10 @@
117
117
  background-color: #FFCCCC;
118
118
  }
119
119
 
120
+ .button_to {
121
+ display: inline-block;
122
+ }
123
+
120
124
  .hidden {
121
125
  display: none;
122
126
  }
@@ -0,0 +1,19 @@
1
+ <header>
2
+ <h1>No template for interactive request</h1>
3
+ </header>
4
+
5
+ <div id="container">
6
+ <h2><%= h @exception.message %></h2>
7
+
8
+ <p class="summary">
9
+ <strong>NOTE!</strong><br>
10
+ Unless told otherwise, Rails expects an action to render a template with the same name,<br>
11
+ contained in a folder named after its controller.
12
+
13
+ If this controller is an API responding with 204 (No Content), <br>
14
+ which does not require a template,
15
+ then this error will occur when trying to access it via browser,<br>
16
+ since we expect an HTML template
17
+ to be rendered for such requests. If that's the case, carry on.
18
+ </p>
19
+ </div>
@@ -0,0 +1,3 @@
1
+ Missing exact template
2
+
3
+ <%= @exception.message %>
@@ -5,7 +5,7 @@
5
5
  <div id="container">
6
6
  <h2><%= h @exception.message %></h2>
7
7
 
8
- <%= render template: "rescues/_source" %>
9
- <%= render template: "rescues/_trace" %>
8
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
9
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
10
10
  <%= render template: "rescues/_request_and_response" %>
11
11
  </div>
@@ -14,7 +14,7 @@
14
14
  </p>
15
15
  <% end %>
16
16
 
17
- <%= render template: "rescues/_trace" %>
17
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
18
18
 
19
19
  <% if @routes_inspector %>
20
20
  <h2>
@@ -11,10 +11,10 @@
11
11
  </p>
12
12
  <pre><code><%= h @exception.message %></code></pre>
13
13
 
14
- <%= render template: "rescues/_source" %>
14
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
15
15
 
16
16
  <p><%= @exception.sub_template_message %></p>
17
17
 
18
- <%= render template: "rescues/_trace" %>
18
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
19
19
  <%= render template: "rescues/_request_and_response" %>
20
20
  </div>
@@ -197,4 +197,7 @@
197
197
 
198
198
  setupMatchPaths();
199
199
  setupRouteToggleHelperLinks();
200
+
201
+ // Focus the search input after page has loaded
202
+ document.getElementById('search').focus();
200
203
  </script>
@@ -21,7 +21,9 @@ module ActionDispatch
21
21
  config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
22
22
  config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
23
23
  config.action_dispatch.use_authenticated_cookie_encryption = false
24
+ config.action_dispatch.use_cookies_with_metadata = false
24
25
  config.action_dispatch.perform_deep_munge = true
26
+ config.action_dispatch.return_only_media_type_on_content_type = true
25
27
 
26
28
  config.action_dispatch.default_headers = {
27
29
  "X-Frame-Options" => "SAMEORIGIN",
@@ -42,6 +44,7 @@ module ActionDispatch
42
44
  ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
43
45
  ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
44
46
  ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers
47
+ ActionDispatch::Response.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_media_type_on_content_type
45
48
 
46
49
  ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
47
50
  ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
@@ -93,6 +93,14 @@ module ActionDispatch
93
93
  @delegate[key.to_s]
94
94
  end
95
95
 
96
+ # Returns the nested value specified by the sequence of keys, returning
97
+ # +nil+ if any intermediate step is +nil+.
98
+ def dig(*keys)
99
+ load_for_read!
100
+ keys = keys.map.with_index { |key, i| i.zero? ? key.to_s : key }
101
+ @delegate.dig(*keys)
102
+ end
103
+
96
104
  # Returns true if the session has the given key or false.
97
105
  def has_key?(key)
98
106
  load_for_read!
@@ -74,8 +74,8 @@ module ActionDispatch
74
74
  # For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
75
75
  # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
76
76
  #
77
- # get 'post/:id' => 'posts#show'
78
- # post 'post/:id' => 'posts#create_comment'
77
+ # get 'post/:id', to: 'posts#show'
78
+ # post 'post/:id', to: 'posts#create_comment'
79
79
  #
80
80
  # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
81
81
  # URL will route to the <tt>show</tt> action.
@@ -83,7 +83,7 @@ module ActionDispatch
83
83
  # If your route needs to respond to more than one HTTP method (or all methods) then using the
84
84
  # <tt>:via</tt> option on <tt>match</tt> is preferable.
85
85
  #
86
- # match 'post/:id' => 'posts#show', via: [:get, :post]
86
+ # match 'post/:id', to: 'posts#show', via: [:get, :post]
87
87
  #
88
88
  # == Named routes
89
89
  #
@@ -94,7 +94,7 @@ module ActionDispatch
94
94
  # Example:
95
95
  #
96
96
  # # In config/routes.rb
97
- # get '/login' => 'accounts#login', as: 'login'
97
+ # get '/login', to: 'accounts#login', as: 'login'
98
98
  #
99
99
  # # With render, redirect_to, tests, etc.
100
100
  # redirect_to login_url
@@ -120,9 +120,9 @@ module ActionDispatch
120
120
  #
121
121
  # # In config/routes.rb
122
122
  # controller :blog do
123
- # get 'blog/show' => :list
124
- # get 'blog/delete' => :delete
125
- # get 'blog/edit' => :edit
123
+ # get 'blog/show', to: :list
124
+ # get 'blog/delete', to: :delete
125
+ # get 'blog/edit', to: :edit
126
126
  # end
127
127
  #
128
128
  # # provides named routes for show, delete, and edit
@@ -132,7 +132,7 @@ module ActionDispatch
132
132
  #
133
133
  # Routes can generate pretty URLs. For example:
134
134
  #
135
- # get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
135
+ # get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
136
136
  # year: /\d{4}/,
137
137
  # month: /\d{1,2}/,
138
138
  # day: /\d{1,2}/
@@ -147,7 +147,7 @@ module ActionDispatch
147
147
  # You can specify a regular expression to define a format for a parameter.
148
148
  #
149
149
  # controller 'geocode' do
150
- # get 'geocode/:postalcode' => :show, constraints: {
150
+ # get 'geocode/:postalcode', to: :show, constraints: {
151
151
  # postalcode: /\d{5}(-\d{4})?/
152
152
  # }
153
153
  # end
@@ -156,13 +156,13 @@ module ActionDispatch
156
156
  # expression modifiers:
157
157
  #
158
158
  # controller 'geocode' do
159
- # get 'geocode/:postalcode' => :show, constraints: {
159
+ # get 'geocode/:postalcode', to: :show, constraints: {
160
160
  # postalcode: /hx\d\d\s\d[a-z]{2}/i
161
161
  # }
162
162
  # end
163
163
  #
164
164
  # controller 'geocode' do
165
- # get 'geocode/:postalcode' => :show, constraints: {
165
+ # get 'geocode/:postalcode', to: :show, constraints: {
166
166
  # postalcode: /# Postalcode format
167
167
  # \d{5} #Prefix
168
168
  # (-\d{4})? #Suffix
@@ -178,13 +178,13 @@ module ActionDispatch
178
178
  #
179
179
  # You can redirect any path to another path using the redirect helper in your router:
180
180
  #
181
- # get "/stories" => redirect("/posts")
181
+ # get "/stories", to: redirect("/posts")
182
182
  #
183
183
  # == Unicode character routes
184
184
  #
185
185
  # You can specify unicode character routes in your router:
186
186
  #
187
- # get "こんにちは" => "welcome#index"
187
+ # get "こんにちは", to: "welcome#index"
188
188
  #
189
189
  # == Routing to Rack Applications
190
190
  #
@@ -192,7 +192,7 @@ module ActionDispatch
192
192
  # index action in the PostsController, you can specify any Rack application
193
193
  # as the endpoint for a matcher:
194
194
  #
195
- # get "/application.js" => Sprockets
195
+ # get "/application.js", to: Sprockets
196
196
  #
197
197
  # == Reloading routes
198
198
  #
@@ -210,8 +210,8 @@ module ActionDispatch
210
210
  # === +assert_routing+
211
211
  #
212
212
  # def test_movie_route_properly_splits
213
- # opts = {controller: "plugin", action: "checkout", id: "2"}
214
- # assert_routing "plugin/checkout/2", opts
213
+ # opts = {controller: "plugin", action: "checkout", id: "2"}
214
+ # assert_routing "plugin/checkout/2", opts
215
215
  # end
216
216
  #
217
217
  # +assert_routing+ lets you test whether or not the route properly resolves into options.
@@ -219,8 +219,8 @@ module ActionDispatch
219
219
  # === +assert_recognizes+
220
220
  #
221
221
  # def test_route_has_options
222
- # opts = {controller: "plugin", action: "show", id: "12"}
223
- # assert_recognizes opts, "/plugins/show/12"
222
+ # opts = {controller: "plugin", action: "show", id: "12"}
223
+ # assert_recognizes opts, "/plugins/show/12"
224
224
  # end
225
225
  #
226
226
  # Note the subtle difference between the two: +assert_routing+ tests that
@@ -243,8 +243,9 @@ module ActionDispatch
243
243
  #
244
244
  # rails routes
245
245
  #
246
- # Target specific controllers by prefixing the command with <tt>-c</tt> option.
247
- #
246
+ # Target a specific controller with <tt>-c</tt>, or grep routes
247
+ # using <tt>-g</tt>. Useful in conjunction with <tt>--expanded</tt>
248
+ # which displays routes vertically.
248
249
  module Routing
249
250
  extend ActiveSupport::Autoload
250
251
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "delegate"
4
- require "active_support/core_ext/string/strip"
4
+ require "io/console/size"
5
5
 
6
6
  module ActionDispatch
7
7
  module Routing
@@ -61,11 +61,11 @@ module ActionDispatch
61
61
  @routes = routes
62
62
  end
63
63
 
64
- def format(formatter, filter = nil)
64
+ def format(formatter, filter = {})
65
65
  routes_to_display = filter_routes(normalize_filter(filter))
66
66
  routes = collect_routes(routes_to_display)
67
67
  if routes.none?
68
- formatter.no_routes(collect_routes(@routes))
68
+ formatter.no_routes(collect_routes(@routes), filter)
69
69
  return formatter.result
70
70
  end
71
71
 
@@ -81,12 +81,12 @@ module ActionDispatch
81
81
  end
82
82
 
83
83
  private
84
-
85
84
  def normalize_filter(filter)
86
- if filter.is_a?(Hash) && filter[:controller]
85
+ if filter[:controller]
87
86
  { controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
88
- elsif filter
89
- { controller: /#{filter}/, action: /#{filter}/, verb: /#{filter}/, name: /#{filter}/, path: /#{filter}/ }
87
+ elsif filter[:grep]
88
+ { controller: /#{filter[:grep]}/, action: /#{filter[:grep]}/,
89
+ verb: /#{filter[:grep]}/, name: /#{filter[:grep]}/, path: /#{filter[:grep]}/ }
90
90
  end
91
91
  end
92
92
 
@@ -126,62 +126,111 @@ module ActionDispatch
126
126
  end
127
127
  end
128
128
 
129
- class ConsoleFormatter
130
- def initialize
131
- @buffer = []
132
- end
129
+ module ConsoleFormatter
130
+ class Base
131
+ def initialize
132
+ @buffer = []
133
+ end
133
134
 
134
- def result
135
- @buffer.join("\n")
136
- end
135
+ def result
136
+ @buffer.join("\n")
137
+ end
137
138
 
138
- def section_title(title)
139
- @buffer << "\n#{title}:"
140
- end
139
+ def section_title(title)
140
+ end
141
141
 
142
- def section(routes)
143
- @buffer << draw_section(routes)
144
- end
142
+ def section(routes)
143
+ end
145
144
 
146
- def header(routes)
147
- @buffer << draw_header(routes)
148
- end
145
+ def header(routes)
146
+ end
149
147
 
150
- def no_routes(routes)
151
- @buffer <<
152
- if routes.none?
153
- <<-MESSAGE.strip_heredoc
154
- You don't have any routes defined!
148
+ def no_routes(routes, filter)
149
+ @buffer <<
150
+ if routes.none?
151
+ <<~MESSAGE
152
+ You don't have any routes defined!
153
+
154
+ Please add some routes in config/routes.rb.
155
+ MESSAGE
156
+ elsif filter.key?(:controller)
157
+ "No routes were found for this controller."
158
+ elsif filter.key?(:grep)
159
+ "No routes were found for this grep pattern."
160
+ end
155
161
 
156
- Please add some routes in config/routes.rb.
157
- MESSAGE
158
- else
159
- "No routes were found for this controller"
162
+ @buffer << "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
160
163
  end
161
- @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
162
164
  end
163
165
 
164
- private
165
- def draw_section(routes)
166
- header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
167
- name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
166
+ class Sheet < Base
167
+ def section_title(title)
168
+ @buffer << "\n#{title}:"
169
+ end
168
170
 
169
- routes.map do |r|
170
- "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
171
- end
171
+ def section(routes)
172
+ @buffer << draw_section(routes)
173
+ end
174
+
175
+ def header(routes)
176
+ @buffer << draw_header(routes)
172
177
  end
173
178
 
174
- def draw_header(routes)
175
- name_width, verb_width, path_width = widths(routes)
179
+ private
180
+
181
+ def draw_section(routes)
182
+ header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
183
+ name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
184
+
185
+ routes.map do |r|
186
+ "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
187
+ end
188
+ end
189
+
190
+ def draw_header(routes)
191
+ name_width, verb_width, path_width = widths(routes)
192
+
193
+ "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
194
+ end
195
+
196
+ def widths(routes)
197
+ [routes.map { |r| r[:name].length }.max || 0,
198
+ routes.map { |r| r[:verb].length }.max || 0,
199
+ routes.map { |r| r[:path].length }.max || 0]
200
+ end
201
+ end
176
202
 
177
- "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
203
+ class Expanded < Base
204
+ def section_title(title)
205
+ @buffer << "\n#{"[ #{title} ]"}"
178
206
  end
179
207
 
180
- def widths(routes)
181
- [routes.map { |r| r[:name].length }.max || 0,
182
- routes.map { |r| r[:verb].length }.max || 0,
183
- routes.map { |r| r[:path].length }.max || 0]
208
+ def section(routes)
209
+ @buffer << draw_expanded_section(routes)
184
210
  end
211
+
212
+ private
213
+
214
+ def draw_expanded_section(routes)
215
+ routes.map.each_with_index do |r, i|
216
+ <<~MESSAGE.chomp
217
+ #{route_header(index: i + 1)}
218
+ Prefix | #{r[:name]}
219
+ Verb | #{r[:verb]}
220
+ URI | #{r[:path]}
221
+ Controller#Action | #{r[:reqs]}
222
+ MESSAGE
223
+ end
224
+ end
225
+
226
+ def route_header(index:)
227
+ console_width = IO.console_size.second
228
+ header_prefix = "--[ Route #{index} ]"
229
+ dash_remainder = [console_width - header_prefix.size, 0].max
230
+
231
+ "#{header_prefix}#{'-' * dash_remainder}"
232
+ end
233
+ end
185
234
  end
186
235
 
187
236
  class HtmlTableFormatter
@@ -203,16 +252,16 @@ module ActionDispatch
203
252
  end
204
253
 
205
254
  def no_routes(*)
206
- @buffer << <<-MESSAGE.strip_heredoc
255
+ @buffer << <<~MESSAGE
207
256
  <p>You don't have any routes defined!</p>
208
257
  <ul>
209
258
  <li>Please add some routes in <tt>config/routes.rb</tt>.</li>
210
259
  <li>
211
260
  For more information about routes, please see the Rails guide
212
- <a href="http://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
261
+ <a href="https://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
213
262
  </li>
214
263
  </ul>
215
- MESSAGE
264
+ MESSAGE
216
265
  end
217
266
 
218
267
  def result