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,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,11 +23,17 @@ module AbstractController
21
23
  key = "#{path}.#{action_name}#{key}"
22
24
  end
23
25
 
26
+ if options[:default] && ActiveSupport::HtmlSafeTranslation.html_safe_translation_key?(key)
27
+ options[:default] = Array(options[:default]).map do |value|
28
+ value.is_a?(String) ? ERB::Util.html_escape(value) : value
29
+ end
30
+ end
31
+
24
32
  ActiveSupport::HtmlSafeTranslation.translate(key, **options)
25
33
  end
26
34
  alias :t :translate
27
35
 
28
- # Delegates to <tt>I18n.localize</tt>.
36
+ # Delegates to `I18n.localize`.
29
37
  def localize(object, **options)
30
38
  I18n.localize(object, **options)
31
39
  end