actionpack 7.1.3.4 → 7.2.0.beta1

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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -541
  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 +11 -10
  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 +155 -117
  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 +119 -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 +209 -201
  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 +58 -57
  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 +9 -5
  70. data/lib/action_dispatch/http/filter_redirect.rb +15 -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 +29 -22
  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 +27 -37
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +71 -71
  79. data/lib/action_dispatch/http/response.rb +61 -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 +670 -635
  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 +30 -13
@@ -1,32 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module AbstractController
4
- # = Abstract Controller \Callbacks
5
- #
6
- # Abstract Controller provides hooks during the life cycle of a controller action.
7
- # Callbacks allow you to trigger logic during this cycle. Available callbacks are:
8
- #
9
- # * <tt>after_action</tt>
10
- # * <tt>append_after_action</tt>
11
- # * <tt>append_around_action</tt>
12
- # * <tt>append_before_action</tt>
13
- # * <tt>around_action</tt>
14
- # * <tt>before_action</tt>
15
- # * <tt>prepend_after_action</tt>
16
- # * <tt>prepend_around_action</tt>
17
- # * <tt>prepend_before_action</tt>
18
- # * <tt>skip_after_action</tt>
19
- # * <tt>skip_around_action</tt>
20
- # * <tt>skip_before_action</tt>
6
+ # # Abstract Controller Callbacks
21
7
  #
22
- # NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
8
+ # Abstract Controller provides hooks during the life cycle of a controller
9
+ # action. Callbacks allow you to trigger logic during this cycle. Available
10
+ # callbacks are:
23
11
  #
12
+ # * `after_action`
13
+ # * `append_after_action`
14
+ # * `append_around_action`
15
+ # * `append_before_action`
16
+ # * `around_action`
17
+ # * `before_action`
18
+ # * `prepend_after_action`
19
+ # * `prepend_around_action`
20
+ # * `prepend_before_action`
21
+ # * `skip_after_action`
22
+ # * `skip_around_action`
23
+ # * `skip_before_action`
24
24
  module Callbacks
25
25
  extend ActiveSupport::Concern
26
26
 
27
- # Uses ActiveSupport::Callbacks as the base functionality. For
28
- # more details on the whole callback system, read the documentation
29
- # for ActiveSupport::Callbacks.
27
+ # Uses ActiveSupport::Callbacks as the base functionality. For more details on
28
+ # the whole callback system, read the documentation for
29
+ # ActiveSupport::Callbacks.
30
30
  include ActiveSupport::Callbacks
31
31
 
32
32
  included do
@@ -72,25 +72,24 @@ module AbstractController
72
72
  end
73
73
 
74
74
  module ClassMethods
75
- # If +:only+ or +:except+ are used, convert the options into the
76
- # +:if+ and +:unless+ options of ActiveSupport::Callbacks.
75
+ # If `:only` or `:except` are used, convert the options into the `:if` and
76
+ # `:unless` options of ActiveSupport::Callbacks.
77
77
  #
78
- # The basic idea is that <tt>:only => :index</tt> gets converted to
79
- # <tt>:if => proc {|c| c.action_name == "index" }</tt>.
78
+ # The basic idea is that `:only => :index` gets converted to `:if => proc {|c|
79
+ # c.action_name == "index" }`.
80
80
  #
81
- # Note that <tt>:only</tt> has priority over <tt>:if</tt> in case they
82
- # are used together.
81
+ # Note that `:only` has priority over `:if` in case they are used together.
83
82
  #
84
- # only: :index, if: -> { true } # the :if option will be ignored.
83
+ # only: :index, if: -> { true } # the :if option will be ignored.
85
84
  #
86
- # Note that <tt>:if</tt> has priority over <tt>:except</tt> in case they
87
- # are used together.
85
+ # Note that `:if` has priority over `:except` in case they are used together.
88
86
  #
89
- # except: :index, if: -> { true } # the :except option will be ignored.
87
+ # except: :index, if: -> { true } # the :except option will be ignored.
88
+ #
89
+ # #### Options
90
+ # * `only` - The callback should be run only for this action.
91
+ # * `except` - The callback should be run for all actions except this action.
90
92
  #
91
- # ==== Options
92
- # * <tt>only</tt> - The callback should be run only for this action.
93
- # * <tt>except</tt> - The callback should be run for all actions except this action.
94
93
  def _normalize_callback_options(options)
95
94
  _normalize_callback_option(options, :only, :if)
96
95
  _normalize_callback_option(options, :except, :unless)
@@ -104,18 +103,20 @@ module AbstractController
104
103
  end
105
104
  end
106
105
 
107
- # Take callback names and an optional callback proc, normalize them,
108
- # then call the block with each callback. This allows us to abstract
109
- # the normalization across several methods that use it.
110
- #
111
- # ==== Parameters
112
- # * <tt>callbacks</tt> - An array of callbacks, with an optional
113
- # options hash as the last parameter.
114
- # * <tt>block</tt> - A proc that should be added to the callbacks.
115
- #
116
- # ==== Block Parameters
117
- # * <tt>name</tt> - The callback to be added.
118
- # * <tt>options</tt> - A hash of options to be used when adding the callback.
106
+ # Take callback names and an optional callback proc, normalize them, then call
107
+ # the block with each callback. This allows us to abstract the normalization
108
+ # across several methods that use it.
109
+ #
110
+ # #### Parameters
111
+ # * `callbacks` - An array of callbacks, with an optional options hash as the
112
+ # last parameter.
113
+ # * `block` - A proc that should be added to the callbacks.
114
+ #
115
+ #
116
+ # #### Block Parameters
117
+ # * `name` - The callback to be added.
118
+ # * `options` - A hash of options to be used when adding the callback.
119
+ #
119
120
  def _insert_callbacks(callbacks, block = nil)
120
121
  options = callbacks.extract_options!
121
122
  callbacks.push(block) if block
@@ -134,20 +135,21 @@ module AbstractController
134
135
  #
135
136
  # Append a callback before actions. See _insert_callbacks for parameter details.
136
137
  #
137
- # If the callback renders or redirects, the action will not run. If there
138
- # are additional callbacks scheduled to run after that callback, they are
139
- # also cancelled.
138
+ # If the callback renders or redirects, the action will not run. If there are
139
+ # additional callbacks scheduled to run after that callback, they are also
140
+ # cancelled.
140
141
 
141
142
  ##
142
143
  # :method: prepend_before_action
143
144
  #
144
145
  # :call-seq: prepend_before_action(names, block)
145
146
  #
146
- # Prepend a callback before actions. See _insert_callbacks for parameter details.
147
+ # Prepend a callback before actions. See _insert_callbacks for parameter
148
+ # details.
147
149
  #
148
- # If the callback renders or redirects, the action will not run. If there
149
- # are additional callbacks scheduled to run after that callback, they are
150
- # also cancelled.
150
+ # If the callback renders or redirects, the action will not run. If there are
151
+ # additional callbacks scheduled to run after that callback, they are also
152
+ # cancelled.
151
153
 
152
154
  ##
153
155
  # :method: skip_before_action
@@ -163,9 +165,9 @@ module AbstractController
163
165
  #
164
166
  # Append a callback before actions. See _insert_callbacks for parameter details.
165
167
  #
166
- # If the callback renders or redirects, the action will not run. If there
167
- # are additional callbacks scheduled to run after that callback, they are
168
- # also cancelled.
168
+ # If the callback renders or redirects, the action will not run. If there are
169
+ # additional callbacks scheduled to run after that callback, they are also
170
+ # cancelled.
169
171
 
170
172
  ##
171
173
  # :method: after_action
@@ -207,7 +209,8 @@ module AbstractController
207
209
  #
208
210
  # :call-seq: prepend_around_action(names, block)
209
211
  #
210
- # Prepend a callback around actions. See _insert_callbacks for parameter details.
212
+ # Prepend a callback around actions. See _insert_callbacks for parameter
213
+ # details.
211
214
 
212
215
  ##
213
216
  # :method: skip_around_action
@@ -222,9 +225,8 @@ module AbstractController
222
225
  # :call-seq: append_around_action(names, block)
223
226
  #
224
227
  # Append a callback around actions. See _insert_callbacks for parameter details.
225
-
226
- # set up before_action, prepend_before_action, skip_before_action, etc.
227
- # for each of before, after, and around.
228
+ # set up before_action, prepend_before_action, skip_before_action, etc. for each
229
+ # of before, after, and around.
228
230
  [:before, :after, :around].each do |callback|
229
231
  define_method "#{callback}_action" do |*names, &blk|
230
232
  _insert_callbacks(names, blk) do |name, options|
@@ -238,8 +240,8 @@ module AbstractController
238
240
  end
239
241
  end
240
242
 
241
- # Skip a before, after or around callback. See _insert_callbacks
242
- # for details on the allowed parameters.
243
+ # Skip a before, after or around callback. See _insert_callbacks for details on
244
+ # the allowed parameters.
243
245
  define_method "skip_#{callback}_action" do |*names|
244
246
  _insert_callbacks(names) do |name, options|
245
247
  skip_callback(:process_action, callback, name, options)
@@ -252,8 +254,8 @@ module AbstractController
252
254
  end
253
255
 
254
256
  private
255
- # Override <tt>AbstractController::Base#process_action</tt> to run the
256
- # <tt>process_action</tt> callbacks around the normal behavior.
257
+ # Override `AbstractController::Base#process_action` to run the `process_action`
258
+ # callbacks around the normal behavior.
257
259
  def process_action(...)
258
260
  run_callbacks(:process_action) do
259
261
  super
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/http/mime_type"
4
6
 
5
7
  module AbstractController
@@ -7,10 +9,9 @@ module AbstractController
7
9
  def self.generate_method_for_mime(mime)
8
10
  sym = mime.is_a?(Symbol) ? mime : mime.to_sym
9
11
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
10
- def #{sym}(*args, &block)
11
- custom(Mime[:#{sym}], *args, &block)
12
+ def #{sym}(...)
13
+ custom(Mime[:#{sym}], ...)
12
14
  end
13
- ruby2_keywords(:#{sym})
14
15
  RUBY
15
16
  end
16
17
 
@@ -23,7 +24,7 @@ module AbstractController
23
24
  end
24
25
 
25
26
  private
26
- def method_missing(symbol, *args, &block)
27
+ def method_missing(symbol, ...)
27
28
  unless mime_constant = Mime[symbol]
28
29
  raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
29
30
  "https://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
@@ -34,11 +35,10 @@ module AbstractController
34
35
 
35
36
  if Mime::SET.include?(mime_constant)
36
37
  AbstractController::Collector.generate_method_for_mime(mime_constant)
37
- public_send(symbol, *args, &block)
38
+ public_send(symbol, ...)
38
39
  else
39
40
  super
40
41
  end
41
42
  end
42
- ruby2_keywords(:method_missing)
43
43
  end
44
44
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module AbstractController
4
6
  def self.deprecator # :nodoc:
5
7
  @deprecator ||= ActiveSupport::Deprecation.new
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module AbstractController
4
6
  class Error < StandardError # :nodoc:
5
7
  end
@@ -1,18 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/dependencies"
4
6
  require "active_support/core_ext/name_error"
5
7
 
6
8
  module AbstractController
7
9
  module Helpers
8
- include ActiveSupport::Deprecation::DeprecatedConstantAccessor
9
10
  extend ActiveSupport::Concern
10
11
 
11
12
  included do
12
13
  class_attribute :_helper_methods, default: Array.new
13
14
 
14
- # This is here so that it is always higher in the inheritance chain than
15
- # the definition in lib/action_view/rendering.rb
15
+ # This is here so that it is always higher in the inheritance chain than the
16
+ # definition in lib/action_view/rendering.rb
16
17
  redefine_singleton_method(:_helpers) do
17
18
  if @_helpers ||= nil
18
19
  @_helpers
@@ -24,23 +25,6 @@ module AbstractController
24
25
  self._helpers = define_helpers_module(self)
25
26
  end
26
27
 
27
- class DeprecatedMissingHelperError < LoadError
28
- def initialize(error, path)
29
- @error = error
30
- @path = "helpers/#{path}.rb"
31
- set_backtrace error.backtrace
32
-
33
- if /^#{path}(\.rb)?$/.match?(error.path)
34
- super("Missing helper file helpers/%s.rb" % path)
35
- else
36
- raise error
37
- end
38
- end
39
- end
40
- deprecate_constant "MissingHelperError", "AbstractController::Helpers::DeprecatedMissingHelperError",
41
- message: "AbstractController::Helpers::MissingHelperError has been deprecated. If a Helper is not present, a NameError will be raised instead.",
42
- deprecator: AbstractController.deprecator
43
-
44
28
  def _helpers
45
29
  self.class._helpers
46
30
  end
@@ -78,9 +62,9 @@ module AbstractController
78
62
  extend Resolution
79
63
 
80
64
  module ClassMethods
81
- # When a class is inherited, wrap its helper module in a new module.
82
- # This ensures that the parent class's module can be changed
83
- # independently of the child class's.
65
+ # When a class is inherited, wrap its helper module in a new module. This
66
+ # ensures that the parent class's module can be changed independently of the
67
+ # child class's.
84
68
  def inherited(klass)
85
69
  # Inherited from parent by default
86
70
  klass._helpers = nil
@@ -97,46 +81,48 @@ module AbstractController
97
81
  # :method: modules_for_helpers
98
82
  # :call-seq: modules_for_helpers(modules_or_helper_prefixes)
99
83
  #
100
- # Given an array of values like the ones accepted by +helper+, this method
84
+ # Given an array of values like the ones accepted by `helper`, this method
101
85
  # returns an array with the corresponding modules, in the same order.
102
86
  #
87
+ # ActionController::Base.modules_for_helpers(["application", "chart", "rubygems"])
88
+ # # => [ApplicationHelper, ChartHelper, RubygemsHelper]
89
+ #
103
90
  #--
104
91
  # Implemented by Resolution#modules_for_helpers.
105
92
 
106
- ##
107
- # :method: all_helpers_from_path
93
+ # :method: # all_helpers_from_path
108
94
  # :call-seq: all_helpers_from_path(path)
109
95
  #
110
96
  # Returns a list of helper names in a given path.
111
97
  #
112
- # ActionController::Base.all_helpers_from_path 'app/helpers'
113
- # # => ["application", "chart", "rubygems"]
98
+ # ActionController::Base.all_helpers_from_path 'app/helpers'
99
+ # # => ["application", "chart", "rubygems"]
114
100
  #
115
101
  #--
116
102
  # Implemented by Resolution#all_helpers_from_path.
117
103
 
118
104
  # Declare a controller method as a helper. For example, the following
119
- # makes the +current_user+ and +logged_in?+ controller methods available
105
+ # makes the `current_user` and `logged_in?` controller methods available
120
106
  # to the view:
121
- # class ApplicationController < ActionController::Base
122
- # helper_method :current_user, :logged_in?
107
+ # class ApplicationController < ActionController::Base
108
+ # helper_method :current_user, :logged_in?
123
109
  #
124
- # private
125
- # def current_user
126
- # @current_user ||= User.find_by(id: session[:user])
127
- # end
110
+ # private
111
+ # def current_user
112
+ # @current_user ||= User.find_by(id: session[:user])
113
+ # end
128
114
  #
129
- # def logged_in?
130
- # current_user != nil
131
- # end
132
- # end
115
+ # def logged_in?
116
+ # current_user != nil
117
+ # end
118
+ # end
133
119
  #
134
120
  # In a view:
135
- # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
121
+ # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
136
122
  #
137
- # ==== Parameters
138
- # * <tt>method[, method]</tt> - A name or names of a method on the controller
139
- # to be made available on the view.
123
+ # #### Parameters
124
+ # * `method[, method]` - A name or names of a method on the controller to be
125
+ # made available on the view.
140
126
  def helper_method(*methods)
141
127
  methods.flatten!
142
128
  self._helper_methods += methods
@@ -145,68 +131,67 @@ module AbstractController
145
131
  file, line = location.path, location.lineno
146
132
 
147
133
  methods.each do |method|
148
- # def current_user(*args, &block)
149
- # controller.send(:'current_user', *args, &block)
134
+ # def current_user(...)
135
+ # controller.send(:'current_user', ...)
150
136
  # end
151
137
  _helpers_for_modification.class_eval <<~ruby_eval.lines.map(&:strip).join(";"), file, line
152
- def #{method}(*args, &block)
153
- controller.send(:'#{method}', *args, &block)
138
+ def #{method}(...)
139
+ controller.send(:'#{method}', ...)
154
140
  end
155
- ruby2_keywords(:'#{method}')
156
141
  ruby_eval
157
142
  end
158
143
  end
159
144
 
160
145
  # Includes the given modules in the template class.
161
146
  #
162
- # Modules can be specified in different ways. All of the following calls
163
- # include +FooHelper+:
147
+ # Modules can be specified in different ways. All of the following calls include
148
+ # `FooHelper`:
164
149
  #
165
- # # Module, recommended.
166
- # helper FooHelper
150
+ # # Module, recommended.
151
+ # helper FooHelper
167
152
  #
168
- # # String/symbol without the "helper" suffix, camel or snake case.
169
- # helper "Foo"
170
- # helper :Foo
171
- # helper "foo"
172
- # helper :foo
153
+ # # String/symbol without the "helper" suffix, camel or snake case.
154
+ # helper "Foo"
155
+ # helper :Foo
156
+ # helper "foo"
157
+ # helper :foo
173
158
  #
174
- # The last two assume that <tt>"foo".camelize</tt> returns "Foo".
159
+ # The last two assume that `"foo".camelize` returns "Foo".
175
160
  #
176
- # When strings or symbols are passed, the method finds the actual module
177
- # object using String#constantize. Therefore, if the module has not been
178
- # yet loaded, it has to be autoloadable, which is normally the case.
161
+ # When strings or symbols are passed, the method finds the actual module object
162
+ # using String#constantize. Therefore, if the module has not been yet loaded, it
163
+ # has to be autoloadable, which is normally the case.
179
164
  #
180
- # Namespaces are supported. The following calls include +Foo::BarHelper+:
165
+ # Namespaces are supported. The following calls include `Foo::BarHelper`:
181
166
  #
182
- # # Module, recommended.
183
- # helper Foo::BarHelper
167
+ # # Module, recommended.
168
+ # helper Foo::BarHelper
184
169
  #
185
- # # String/symbol without the "helper" suffix, camel or snake case.
186
- # helper "Foo::Bar"
187
- # helper :"Foo::Bar"
188
- # helper "foo/bar"
189
- # helper :"foo/bar"
170
+ # # String/symbol without the "helper" suffix, camel or snake case.
171
+ # helper "Foo::Bar"
172
+ # helper :"Foo::Bar"
173
+ # helper "foo/bar"
174
+ # helper :"foo/bar"
190
175
  #
191
- # The last two assume that <tt>"foo/bar".camelize</tt> returns "Foo::Bar".
176
+ # The last two assume that `"foo/bar".camelize` returns "Foo::Bar".
192
177
  #
193
- # The method accepts a block too. If present, the block is evaluated in
194
- # the context of the controller helper module. This simple call makes the
195
- # +wadus+ method available in templates of the enclosing controller:
178
+ # The method accepts a block too. If present, the block is evaluated in the
179
+ # context of the controller helper module. This simple call makes the `wadus`
180
+ # method available in templates of the enclosing controller:
196
181
  #
197
- # helper do
198
- # def wadus
199
- # "wadus"
182
+ # helper do
183
+ # def wadus
184
+ # "wadus"
185
+ # end
200
186
  # end
201
- # end
202
187
  #
203
188
  # Furthermore, all the above styles can be mixed together:
204
189
  #
205
- # helper FooHelper, "woo", "bar/baz" do
206
- # def wadus
207
- # "wadus"
190
+ # helper FooHelper, "woo", "bar/baz" do
191
+ # def wadus
192
+ # "wadus"
193
+ # end
208
194
  # end
209
- # end
210
195
  #
211
196
  def helper(*args, &block)
212
197
  modules_for_helpers(args).each do |mod|
@@ -217,8 +202,8 @@ module AbstractController
217
202
  _helpers_for_modification.module_eval(&block) if block_given?
218
203
  end
219
204
 
220
- # Clears up all existing helpers in this class, only keeping the helper
221
- # with the same name as this class.
205
+ # Clears up all existing helpers in this class, only keeping the helper with the
206
+ # same name as this class.
222
207
  def clear_helpers
223
208
  inherited_helper_methods = _helper_methods
224
209
  self._helpers = Module.new
@@ -237,8 +222,8 @@ module AbstractController
237
222
 
238
223
  private
239
224
  def define_helpers_module(klass, helpers = nil)
240
- # In some tests inherited is called explicitly. In that case, just
241
- # return the module from the first time it was defined
225
+ # In some tests inherited is called explicitly. In that case, just return the
226
+ # module from the first time it was defined
242
227
  return klass.const_get(:HelperMethods) if klass.const_defined?(:HelperMethods, false)
243
228
 
244
229
  mod = Module.new
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/benchmarkable"
4
6
 
5
7
  module AbstractController
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/module/introspection"
4
6
 
5
7
  module AbstractController
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "abstract_controller/error"
4
6
  require "action_view"
5
7
  require "action_view/view_paths"
@@ -19,9 +21,9 @@ module AbstractController
19
21
  include ActionView::ViewPaths
20
22
 
21
23
  # Normalizes arguments and options, and then delegates to render_to_body and
22
- # sticks the result in <tt>self.response_body</tt>.
24
+ # sticks the result in `self.response_body`.
23
25
  #
24
- # Supported options depend on the underlying +render_to_body+ implementation.
26
+ # Supported options depend on the underlying `render_to_body` implementation.
25
27
  def render(*args, &block)
26
28
  options = _normalize_render(*args, &block)
27
29
  rendered_body = render_to_body(options)
@@ -35,11 +37,11 @@ module AbstractController
35
37
  end
36
38
 
37
39
  # Similar to #render, but only returns the rendered template as a string,
38
- # instead of setting +self.response_body+.
40
+ # instead of setting `self.response_body`.
39
41
  #
40
- # If a component extends the semantics of +response_body+ (as ActionController
41
- # extends it to be anything that responds to the method each), this method
42
- # needs to be overridden in order to still return a string.
42
+ # If a component extends the semantics of `response_body` (as ActionController
43
+ # extends it to be anything that responds to the method each), this method needs
44
+ # to be overridden in order to still return a string.
43
45
  def render_to_string(*args, &block)
44
46
  options = _normalize_render(*args, &block)
45
47
  render_to_body(options)
@@ -49,15 +51,15 @@ module AbstractController
49
51
  def render_to_body(options = {})
50
52
  end
51
53
 
52
- # Returns +Content-Type+ of rendered content.
54
+ # Returns `Content-Type` of rendered content.
53
55
  def rendered_format
54
56
  Mime[:text]
55
57
  end
56
58
 
57
59
  DEFAULT_PROTECTED_INSTANCE_VARIABLES = %i(@_action_name @_response_body @_formats @_prefixes)
58
60
 
59
- # This method should return a hash with assigns.
60
- # You can overwrite this configuration per controller.
61
+ # This method should return a hash with assigns. You can overwrite this
62
+ # configuration per controller.
61
63
  def view_assigns
62
64
  variables = instance_variables - _protected_ivars
63
65
 
@@ -67,9 +69,8 @@ module AbstractController
67
69
  end
68
70
 
69
71
  private
70
- # Normalize args by converting <tt>render "foo"</tt> to
71
- # <tt>render action: "foo"</tt> and <tt>render "foo/bar"</tt> to
72
- # <tt>render file: "foo/bar"</tt>.
72
+ # Normalize args by converting `render "foo"` to `render action: "foo"` and
73
+ # `render "foo/bar"` to `render file: "foo/bar"`.
73
74
  def _normalize_args(action = nil, options = {}) # :doc:
74
75
  if action.respond_to?(:permitted?)
75
76
  if action.permitted?
@@ -1,17 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/html_safe_translation"
4
6
 
5
7
  module AbstractController
6
8
  module Translation
7
- # Delegates to <tt>I18n.translate</tt>.
9
+ # Delegates to `I18n.translate`.
8
10
  #
9
11
  # When the given key starts with a period, it will be scoped by the current
10
- # controller and action. So if you call <tt>translate(".foo")</tt> from
11
- # <tt>PeopleController#index</tt>, it will convert the call to
12
- # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
13
- # to translate many keys within the same controller / action and gives you a
14
- # simple framework for scoping them consistently.
12
+ # controller and action. So if you call `translate(".foo")` from
13
+ # `PeopleController#index`, it will convert the call to
14
+ # `I18n.translate("people.index.foo")`. This makes it less repetitive to
15
+ # translate many keys within the same controller / action and gives you a simple
16
+ # framework for scoping them consistently.
15
17
  def translate(key, **options)
16
18
  if key&.start_with?(".")
17
19
  path = controller_path.tr("/", ".")
@@ -21,9 +23,8 @@ module AbstractController
21
23
  key = "#{path}.#{action_name}#{key}"
22
24
  end
23
25
 
24
- if options[:default]
25
- options[:default] = [options[:default]] unless options[:default].is_a?(Array)
26
- options[:default] = options[:default].map do |value|
26
+ if options[:default] && ActiveSupport::HtmlSafeTranslation.html_safe_translation_key?(key)
27
+ options[:default] = Array(options[:default]).map do |value|
27
28
  value.is_a?(String) ? ERB::Util.html_escape(value) : value
28
29
  end
29
30
  end
@@ -32,7 +33,7 @@ module AbstractController
32
33
  end
33
34
  alias :t :translate
34
35
 
35
- # Delegates to <tt>I18n.localize</tt>.
36
+ # Delegates to `I18n.localize`.
36
37
  def localize(object, **options)
37
38
  I18n.localize(object, **options)
38
39
  end