actionpack 7.1.5.1 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -604
  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 +72 -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 +12 -13
  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 +75 -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 +187 -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 +116 -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 +483 -478
  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 +148 -129
  63. data/lib/action_controller.rb +5 -1
  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 +40 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +9 -5
  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 +25 -21
  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 +19 -36
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +70 -71
  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 +2 -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 +76 -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 +16 -16
  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/routes/_table.html.erb +1 -1
  125. data/lib/action_dispatch/railtie.rb +2 -3
  126. data/lib/action_dispatch/request/session.rb +23 -21
  127. data/lib/action_dispatch/request/utils.rb +2 -0
  128. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  129. data/lib/action_dispatch/routing/inspector.rb +5 -3
  130. data/lib/action_dispatch/routing/mapper.rb +622 -623
  131. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  132. data/lib/action_dispatch/routing/redirection.rb +37 -32
  133. data/lib/action_dispatch/routing/route_set.rb +59 -45
  134. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  135. data/lib/action_dispatch/routing/url_for.rb +130 -125
  136. data/lib/action_dispatch/routing.rb +150 -148
  137. data/lib/action_dispatch/system_test_case.rb +91 -81
  138. data/lib/action_dispatch/system_testing/browser.rb +4 -2
  139. data/lib/action_dispatch/system_testing/driver.rb +2 -0
  140. data/lib/action_dispatch/system_testing/server.rb +2 -0
  141. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  142. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  143. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  144. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  145. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  146. data/lib/action_dispatch/testing/assertions.rb +2 -0
  147. data/lib/action_dispatch/testing/integration.rb +223 -222
  148. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  149. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  150. data/lib/action_dispatch/testing/test_process.rb +12 -8
  151. data/lib/action_dispatch/testing/test_request.rb +3 -1
  152. data/lib/action_dispatch/testing/test_response.rb +27 -26
  153. data/lib/action_dispatch.rb +22 -28
  154. data/lib/action_pack/gem_version.rb +5 -3
  155. data/lib/action_pack/version.rb +3 -1
  156. data/lib/action_pack.rb +17 -16
  157. metadata +34 -11
@@ -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,50 @@ 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?
123
107
  #
124
- # private
125
- # def current_user
126
- # @current_user ||= User.find_by(id: session[:user])
127
- # end
108
+ # class ApplicationController < ActionController::Base
109
+ # helper_method :current_user, :logged_in?
128
110
  #
129
- # def logged_in?
130
- # current_user != nil
131
- # end
132
- # end
111
+ # private
112
+ # def current_user
113
+ # @current_user ||= User.find_by(id: session[:user])
114
+ # end
115
+ #
116
+ # def logged_in?
117
+ # current_user != nil
118
+ # end
119
+ # end
133
120
  #
134
121
  # In a view:
135
- # <% 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
+ # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
124
+ #
125
+ # #### Parameters
126
+ # * `method[, method]` - A name or names of a method on the controller to be
127
+ # made available on the view.
140
128
  def helper_method(*methods)
141
129
  methods.flatten!
142
130
  self._helper_methods += methods
@@ -145,68 +133,67 @@ module AbstractController
145
133
  file, line = location.path, location.lineno
146
134
 
147
135
  methods.each do |method|
148
- # def current_user(*args, &block)
149
- # controller.send(:'current_user', *args, &block)
136
+ # def current_user(...)
137
+ # controller.send(:'current_user', ...)
150
138
  # end
151
139
  _helpers_for_modification.class_eval <<~ruby_eval.lines.map(&:strip).join(";"), file, line
152
- def #{method}(*args, &block)
153
- controller.send(:'#{method}', *args, &block)
140
+ def #{method}(...)
141
+ controller.send(:'#{method}', ...)
154
142
  end
155
- ruby2_keywords(:'#{method}')
156
143
  ruby_eval
157
144
  end
158
145
  end
159
146
 
160
147
  # Includes the given modules in the template class.
161
148
  #
162
- # Modules can be specified in different ways. All of the following calls
163
- # include +FooHelper+:
149
+ # Modules can be specified in different ways. All of the following calls include
150
+ # `FooHelper`:
164
151
  #
165
- # # Module, recommended.
166
- # helper FooHelper
152
+ # # Module, recommended.
153
+ # helper FooHelper
167
154
  #
168
- # # String/symbol without the "helper" suffix, camel or snake case.
169
- # helper "Foo"
170
- # helper :Foo
171
- # helper "foo"
172
- # helper :foo
155
+ # # String/symbol without the "helper" suffix, camel or snake case.
156
+ # helper "Foo"
157
+ # helper :Foo
158
+ # helper "foo"
159
+ # helper :foo
173
160
  #
174
- # The last two assume that <tt>"foo".camelize</tt> returns "Foo".
161
+ # The last two assume that `"foo".camelize` returns "Foo".
175
162
  #
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.
163
+ # When strings or symbols are passed, the method finds the actual module object
164
+ # using String#constantize. Therefore, if the module has not been yet loaded, it
165
+ # has to be autoloadable, which is normally the case.
179
166
  #
180
- # Namespaces are supported. The following calls include +Foo::BarHelper+:
167
+ # Namespaces are supported. The following calls include `Foo::BarHelper`:
181
168
  #
182
- # # Module, recommended.
183
- # helper Foo::BarHelper
169
+ # # Module, recommended.
170
+ # helper Foo::BarHelper
184
171
  #
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"
172
+ # # String/symbol without the "helper" suffix, camel or snake case.
173
+ # helper "Foo::Bar"
174
+ # helper :"Foo::Bar"
175
+ # helper "foo/bar"
176
+ # helper :"foo/bar"
190
177
  #
191
- # The last two assume that <tt>"foo/bar".camelize</tt> returns "Foo::Bar".
178
+ # The last two assume that `"foo/bar".camelize` returns "Foo::Bar".
192
179
  #
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:
180
+ # The method accepts a block too. If present, the block is evaluated in the
181
+ # context of the controller helper module. This simple call makes the `wadus`
182
+ # method available in templates of the enclosing controller:
196
183
  #
197
- # helper do
198
- # def wadus
199
- # "wadus"
184
+ # helper do
185
+ # def wadus
186
+ # "wadus"
187
+ # end
200
188
  # end
201
- # end
202
189
  #
203
190
  # Furthermore, all the above styles can be mixed together:
204
191
  #
205
- # helper FooHelper, "woo", "bar/baz" do
206
- # def wadus
207
- # "wadus"
192
+ # helper FooHelper, "woo", "bar/baz" do
193
+ # def wadus
194
+ # "wadus"
195
+ # end
208
196
  # end
209
- # end
210
197
  #
211
198
  def helper(*args, &block)
212
199
  modules_for_helpers(args).each do |mod|
@@ -217,8 +204,8 @@ module AbstractController
217
204
  _helpers_for_modification.module_eval(&block) if block_given?
218
205
  end
219
206
 
220
- # Clears up all existing helpers in this class, only keeping the helper
221
- # with the same name as this class.
207
+ # Clears up all existing helpers in this class, only keeping the helper with the
208
+ # same name as this class.
222
209
  def clear_helpers
223
210
  inherited_helper_methods = _helper_methods
224
211
  self._helpers = Module.new
@@ -237,8 +224,8 @@ module AbstractController
237
224
 
238
225
  private
239
226
  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
227
+ # In some tests inherited is called explicitly. In that case, just return the
228
+ # module from the first time it was defined
242
229
  return klass.const_get(:HelperMethods) if klass.const_defined?(:HelperMethods, false)
243
230
 
244
231
  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,12 +23,9 @@ module AbstractController
21
23
  key = "#{path}.#{action_name}#{key}"
22
24
  end
23
25
 
24
- if ActiveSupport::HtmlSafeTranslation.html_safe_translation_key?(key)
25
- if options[:default]
26
- options[:default] = [options[:default]] unless options[:default].is_a?(Array)
27
- options[:default] = options[:default].map do |value|
28
- value.is_a?(String) ? ERB::Util.html_escape(value) : value
29
- end
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
30
29
  end
31
30
  end
32
31
 
@@ -34,7 +33,7 @@ module AbstractController
34
33
  end
35
34
  alias :t :translate
36
35
 
37
- # Delegates to <tt>I18n.localize</tt>.
36
+ # Delegates to `I18n.localize`.
38
37
  def localize(object, **options)
39
38
  I18n.localize(object, **options)
40
39
  end