actionpack 7.1.3 → 7.2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -501
  3. data/lib/abstract_controller/asset_paths.rb +2 -0
  4. data/lib/abstract_controller/base.rb +102 -98
  5. data/lib/abstract_controller/caching/fragments.rb +50 -53
  6. data/lib/abstract_controller/caching.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +66 -64
  8. data/lib/abstract_controller/collector.rb +6 -6
  9. data/lib/abstract_controller/deprecator.rb +2 -0
  10. data/lib/abstract_controller/error.rb +2 -0
  11. data/lib/abstract_controller/helpers.rb +70 -85
  12. data/lib/abstract_controller/logger.rb +2 -0
  13. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  14. data/lib/abstract_controller/rendering.rb +13 -12
  15. data/lib/abstract_controller/translation.rb +15 -7
  16. data/lib/abstract_controller/url_for.rb +8 -6
  17. data/lib/abstract_controller.rb +2 -0
  18. data/lib/action_controller/api/api_rendering.rb +2 -0
  19. data/lib/action_controller/api.rb +74 -72
  20. data/lib/action_controller/base.rb +198 -126
  21. data/lib/action_controller/caching.rb +15 -12
  22. data/lib/action_controller/deprecator.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +20 -17
  24. data/lib/action_controller/log_subscriber.rb +3 -1
  25. data/lib/action_controller/metal/allow_browser.rb +123 -0
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +188 -174
  28. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  29. data/lib/action_controller/metal/cookies.rb +4 -2
  30. data/lib/action_controller/metal/data_streaming.rb +64 -55
  31. data/lib/action_controller/metal/default_headers.rb +5 -3
  32. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  34. data/lib/action_controller/metal/exceptions.rb +11 -9
  35. data/lib/action_controller/metal/flash.rb +12 -10
  36. data/lib/action_controller/metal/head.rb +12 -10
  37. data/lib/action_controller/metal/helpers.rb +63 -55
  38. data/lib/action_controller/metal/http_authentication.rb +210 -205
  39. data/lib/action_controller/metal/implicit_render.rb +17 -15
  40. data/lib/action_controller/metal/instrumentation.rb +15 -12
  41. data/lib/action_controller/metal/live.rb +113 -107
  42. data/lib/action_controller/metal/logging.rb +6 -4
  43. data/lib/action_controller/metal/mime_responds.rb +151 -142
  44. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  45. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  46. data/lib/action_controller/metal/permissions_policy.rb +13 -12
  47. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  48. data/lib/action_controller/metal/redirecting.rb +108 -82
  49. data/lib/action_controller/metal/renderers.rb +50 -49
  50. data/lib/action_controller/metal/rendering.rb +103 -75
  51. data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
  52. data/lib/action_controller/metal/rescue.rb +11 -9
  53. data/lib/action_controller/metal/streaming.rb +138 -136
  54. data/lib/action_controller/metal/strong_parameters.rb +525 -480
  55. data/lib/action_controller/metal/testing.rb +2 -0
  56. data/lib/action_controller/metal/url_for.rb +17 -15
  57. data/lib/action_controller/metal.rb +86 -60
  58. data/lib/action_controller/railtie.rb +3 -0
  59. data/lib/action_controller/railties/helpers.rb +2 -0
  60. data/lib/action_controller/renderer.rb +42 -36
  61. data/lib/action_controller/template_assertions.rb +4 -2
  62. data/lib/action_controller/test_case.rb +146 -126
  63. data/lib/action_controller.rb +10 -3
  64. data/lib/action_dispatch/constants.rb +2 -0
  65. data/lib/action_dispatch/deprecator.rb +2 -0
  66. data/lib/action_dispatch/http/cache.rb +27 -26
  67. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  68. data/lib/action_dispatch/http/content_security_policy.rb +44 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +18 -9
  70. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  71. data/lib/action_dispatch/http/headers.rb +22 -22
  72. data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
  73. data/lib/action_dispatch/http/mime_type.rb +31 -24
  74. data/lib/action_dispatch/http/mime_types.rb +2 -0
  75. data/lib/action_dispatch/http/parameters.rb +11 -9
  76. data/lib/action_dispatch/http/permissions_policy.rb +20 -44
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +94 -75
  79. data/lib/action_dispatch/http/response.rb +73 -61
  80. data/lib/action_dispatch/http/upload.rb +18 -16
  81. data/lib/action_dispatch/http/url.rb +75 -73
  82. data/lib/action_dispatch/journey/formatter.rb +13 -6
  83. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  84. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  85. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  86. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  88. data/lib/action_dispatch/journey/parser.rb +4 -3
  89. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  90. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  91. data/lib/action_dispatch/journey/route.rb +9 -7
  92. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  93. data/lib/action_dispatch/journey/router.rb +4 -2
  94. data/lib/action_dispatch/journey/routes.rb +4 -2
  95. data/lib/action_dispatch/journey/scanner.rb +4 -2
  96. data/lib/action_dispatch/journey/visitors.rb +2 -0
  97. data/lib/action_dispatch/journey.rb +2 -0
  98. data/lib/action_dispatch/log_subscriber.rb +2 -0
  99. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  100. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  101. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  102. data/lib/action_dispatch/middleware/cookies.rb +119 -104
  103. data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
  104. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  105. data/lib/action_dispatch/middleware/debug_view.rb +2 -0
  106. data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
  107. data/lib/action_dispatch/middleware/executor.rb +8 -0
  108. data/lib/action_dispatch/middleware/flash.rb +63 -51
  109. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  110. data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
  111. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  112. data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
  113. data/lib/action_dispatch/middleware/request_id.rb +14 -9
  114. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
  120. data/lib/action_dispatch/middleware/ssl.rb +43 -40
  121. data/lib/action_dispatch/middleware/stack.rb +11 -10
  122. data/lib/action_dispatch/middleware/static.rb +33 -31
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
  124. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
  125. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  126. data/lib/action_dispatch/railtie.rb +2 -4
  127. data/lib/action_dispatch/request/session.rb +23 -21
  128. data/lib/action_dispatch/request/utils.rb +2 -0
  129. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  130. data/lib/action_dispatch/routing/inspector.rb +5 -3
  131. data/lib/action_dispatch/routing/mapper.rb +671 -636
  132. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  133. data/lib/action_dispatch/routing/redirection.rb +37 -32
  134. data/lib/action_dispatch/routing/route_set.rb +59 -45
  135. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  136. data/lib/action_dispatch/routing/url_for.rb +130 -125
  137. data/lib/action_dispatch/routing.rb +150 -148
  138. data/lib/action_dispatch/system_test_case.rb +91 -81
  139. data/lib/action_dispatch/system_testing/browser.rb +10 -3
  140. data/lib/action_dispatch/system_testing/driver.rb +3 -1
  141. data/lib/action_dispatch/system_testing/server.rb +2 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  143. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  144. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  145. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  146. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  147. data/lib/action_dispatch/testing/assertions.rb +2 -0
  148. data/lib/action_dispatch/testing/integration.rb +223 -222
  149. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  150. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  151. data/lib/action_dispatch/testing/test_process.rb +12 -8
  152. data/lib/action_dispatch/testing/test_request.rb +3 -1
  153. data/lib/action_dispatch/testing/test_response.rb +27 -26
  154. data/lib/action_dispatch.rb +22 -28
  155. data/lib/action_pack/gem_version.rb +6 -4
  156. data/lib/action_pack/version.rb +3 -1
  157. data/lib/action_pack.rb +17 -16
  158. metadata +39 -16
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/hash/indifferent_access"
4
6
  require "active_support/core_ext/array/wrap"
5
7
  require "active_support/core_ext/string/filters"
@@ -14,11 +16,11 @@ require "yaml"
14
16
  module ActionController
15
17
  # Raised when a required parameter is missing.
16
18
  #
17
- # params = ActionController::Parameters.new(a: {})
18
- # params.fetch(:b)
19
- # # => ActionController::ParameterMissing: param is missing or the value is empty: b
20
- # params.require(:a)
21
- # # => ActionController::ParameterMissing: param is missing or the value is empty: a
19
+ # params = ActionController::Parameters.new(a: {})
20
+ # params.fetch(:b)
21
+ # # => ActionController::ParameterMissing: param is missing or the value is empty: b
22
+ # params.require(:a)
23
+ # # => ActionController::ParameterMissing: param is missing or the value is empty: a
22
24
  class ParameterMissing < KeyError
23
25
  attr_reader :param, :keys # :nodoc:
24
26
 
@@ -38,12 +40,12 @@ module ActionController
38
40
  end
39
41
 
40
42
  # Raised when a supplied parameter is not expected and
41
- # ActionController::Parameters.action_on_unpermitted_parameters
42
- # is set to <tt>:raise</tt>.
43
+ # ActionController::Parameters.action_on_unpermitted_parameters is set to
44
+ # `:raise`.
43
45
  #
44
- # params = ActionController::Parameters.new(a: "123", b: "456")
45
- # params.permit(:c)
46
- # # => ActionController::UnpermittedParameters: found unpermitted parameters: :a, :b
46
+ # params = ActionController::Parameters.new(a: "123", b: "456")
47
+ # params.permit(:c)
48
+ # # => ActionController::UnpermittedParameters: found unpermitted parameters: :a, :b
47
49
  class UnpermittedParameters < IndexError
48
50
  attr_reader :params # :nodoc:
49
51
 
@@ -53,12 +55,12 @@ module ActionController
53
55
  end
54
56
  end
55
57
 
56
- # Raised when a Parameters instance is not marked as permitted and
57
- # an operation to transform it to hash is called.
58
+ # Raised when a Parameters instance is not marked as permitted and an operation
59
+ # to transform it to hash is called.
58
60
  #
59
- # params = ActionController::Parameters.new(a: "123", b: "456")
60
- # params.to_h
61
- # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
61
+ # params = ActionController::Parameters.new(a: "123", b: "456")
62
+ # params.to_h
63
+ # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
62
64
  class UnfilteredParameters < ArgumentError
63
65
  def initialize # :nodoc:
64
66
  super("unable to convert unpermitted parameters to hash")
@@ -67,12 +69,12 @@ module ActionController
67
69
 
68
70
  # Raised when initializing Parameters with keys that aren't strings or symbols.
69
71
  #
70
- # ActionController::Parameters.new(123 => 456)
71
- # # => ActionController::InvalidParameterKey: all keys must be Strings or Symbols, got: Integer
72
+ # ActionController::Parameters.new(123 => 456)
73
+ # # => ActionController::InvalidParameterKey: all keys must be Strings or Symbols, got: Integer
72
74
  class InvalidParameterKey < ArgumentError
73
75
  end
74
76
 
75
- # = Action Controller \Parameters
77
+ # # Action Controller Parameters
76
78
  #
77
79
  # Allows you to choose which attributes should be permitted for mass updating
78
80
  # and thus prevent accidentally exposing that which shouldn't be exposed.
@@ -80,63 +82,68 @@ module ActionController
80
82
  # used to mark parameters as required. The latter is used to set the parameter
81
83
  # as permitted and limit which attributes should be allowed for mass updating.
82
84
  #
83
- # params = ActionController::Parameters.new({
84
- # person: {
85
- # name: "Francesco",
86
- # age: 22,
87
- # role: "admin"
88
- # }
89
- # })
85
+ # params = ActionController::Parameters.new({
86
+ # person: {
87
+ # name: "Francesco",
88
+ # age: 22,
89
+ # role: "admin"
90
+ # }
91
+ # })
90
92
  #
91
- # permitted = params.require(:person).permit(:name, :age)
92
- # permitted # => #<ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
93
- # permitted.permitted? # => true
93
+ # permitted = params.require(:person).permit(:name, :age)
94
+ # permitted # => #<ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
95
+ # permitted.permitted? # => true
94
96
  #
95
- # Person.first.update!(permitted)
96
- # # => #<Person id: 1, name: "Francesco", age: 22, role: "user">
97
+ # Person.first.update!(permitted)
98
+ # # => #<Person id: 1, name: "Francesco", age: 22, role: "user">
97
99
  #
98
100
  # It provides two options that controls the top-level behavior of new instances:
99
101
  #
100
- # * +permit_all_parameters+ - If it's +true+, all the parameters will be
101
- # permitted by default. The default is +false+.
102
- # * +action_on_unpermitted_parameters+ - Controls behavior when parameters that are not explicitly
103
- # permitted are found. The default value is <tt>:log</tt> in test and development environments,
104
- # +false+ otherwise. The values can be:
105
- # * +false+ to take no action.
106
- # * <tt>:log</tt> to emit an <tt>ActiveSupport::Notifications.instrument</tt> event on the
107
- # <tt>unpermitted_parameters.action_controller</tt> topic and log at the DEBUG level.
108
- # * <tt>:raise</tt> to raise an ActionController::UnpermittedParameters exception.
102
+ # * `permit_all_parameters` - If it's `true`, all the parameters will be
103
+ # permitted by default. The default is `false`.
104
+ # * `action_on_unpermitted_parameters` - Controls behavior when parameters
105
+ # that are not explicitly permitted are found. The default value is `:log`
106
+ # in test and development environments, `false` otherwise. The values can
107
+ # be:
108
+ # * `false` to take no action.
109
+ # * `:log` to emit an `ActiveSupport::Notifications.instrument` event on
110
+ # the `unpermitted_parameters.action_controller` topic and log at the
111
+ # DEBUG level.
112
+ # * `:raise` to raise an ActionController::UnpermittedParameters
113
+ # exception.
114
+ #
115
+ #
109
116
  #
110
117
  # Examples:
111
118
  #
112
- # params = ActionController::Parameters.new
113
- # params.permitted? # => false
119
+ # params = ActionController::Parameters.new
120
+ # params.permitted? # => false
114
121
  #
115
- # ActionController::Parameters.permit_all_parameters = true
122
+ # ActionController::Parameters.permit_all_parameters = true
116
123
  #
117
- # params = ActionController::Parameters.new
118
- # params.permitted? # => true
124
+ # params = ActionController::Parameters.new
125
+ # params.permitted? # => true
119
126
  #
120
- # params = ActionController::Parameters.new(a: "123", b: "456")
121
- # params.permit(:c)
122
- # # => #<ActionController::Parameters {} permitted: true>
127
+ # params = ActionController::Parameters.new(a: "123", b: "456")
128
+ # params.permit(:c)
129
+ # # => #<ActionController::Parameters {} permitted: true>
123
130
  #
124
- # ActionController::Parameters.action_on_unpermitted_parameters = :raise
131
+ # ActionController::Parameters.action_on_unpermitted_parameters = :raise
125
132
  #
126
- # params = ActionController::Parameters.new(a: "123", b: "456")
127
- # params.permit(:c)
128
- # # => ActionController::UnpermittedParameters: found unpermitted keys: a, b
133
+ # params = ActionController::Parameters.new(a: "123", b: "456")
134
+ # params.permit(:c)
135
+ # # => ActionController::UnpermittedParameters: found unpermitted keys: a, b
129
136
  #
130
137
  # Please note that these options *are not thread-safe*. In a multi-threaded
131
138
  # environment they should only be set once at boot-time and never mutated at
132
139
  # runtime.
133
140
  #
134
- # You can fetch values of +ActionController::Parameters+ using either
135
- # <tt>:key</tt> or <tt>"key"</tt>.
141
+ # You can fetch values of `ActionController::Parameters` using either `:key` or
142
+ # `"key"`.
136
143
  #
137
- # params = ActionController::Parameters.new(key: "value")
138
- # params[:key] # => "value"
139
- # params["key"] # => "value"
144
+ # params = ActionController::Parameters.new(key: "value")
145
+ # params[:key] # => "value"
146
+ # params["key"] # => "value"
140
147
  class Parameters
141
148
  include ActiveSupport::DeepMergeable
142
149
 
@@ -148,12 +155,13 @@ module ActionController
148
155
  # :method: deep_merge
149
156
  #
150
157
  # :call-seq:
151
- # deep_merge(other_hash, &block)
158
+ # deep_merge(other_hash, &block)
152
159
  #
153
- # Returns a new +ActionController::Parameters+ instance with +self+ and +other_hash+ merged recursively.
160
+ # Returns a new `ActionController::Parameters` instance with `self` and
161
+ # `other_hash` merged recursively.
154
162
  #
155
- # Like with <tt>Hash#merge</tt> in the standard library, a block can be provided
156
- # to merge values.
163
+ # Like with `Hash#merge` in the standard library, a block can be provided to
164
+ # merge values.
157
165
  #
158
166
  #--
159
167
  # Implemented by ActiveSupport::DeepMergeable#deep_merge.
@@ -162,9 +170,9 @@ module ActionController
162
170
  # :method: deep_merge!
163
171
  #
164
172
  # :call-seq:
165
- # deep_merge!(other_hash, &block)
173
+ # deep_merge!(other_hash, &block)
166
174
  #
167
- # Same as +#deep_merge+, but modifies +self+.
175
+ # Same as `#deep_merge`, but modifies `self`.
168
176
  #
169
177
  #--
170
178
  # Implemented by ActiveSupport::DeepMergeable#deep_merge!.
@@ -173,7 +181,7 @@ module ActionController
173
181
  # :method: as_json
174
182
  #
175
183
  # :call-seq:
176
- # as_json(options=nil)
184
+ # as_json(options=nil)
177
185
  #
178
186
  # Returns a hash that can be used as the JSON representation for the parameters.
179
187
 
@@ -181,16 +189,16 @@ module ActionController
181
189
  # :method: each_key
182
190
  #
183
191
  # :call-seq:
184
- # each_key(&block)
192
+ # each_key(&block)
185
193
  #
186
- # Calls block once for each key in the parameters, passing the key.
187
- # If no block is given, an enumerator is returned instead.
194
+ # Calls block once for each key in the parameters, passing the key. If no block
195
+ # is given, an enumerator is returned instead.
188
196
 
189
197
  ##
190
198
  # :method: empty?
191
199
  #
192
200
  # :call-seq:
193
- # empty?()
201
+ # empty?()
194
202
  #
195
203
  # Returns true if the parameters have no key/value pairs.
196
204
 
@@ -198,7 +206,7 @@ module ActionController
198
206
  # :method: exclude?
199
207
  #
200
208
  # :call-seq:
201
- # exclude?(key)
209
+ # exclude?(key)
202
210
  #
203
211
  # Returns true if the given key is not present in the parameters.
204
212
 
@@ -206,7 +214,7 @@ module ActionController
206
214
  # :method: include?
207
215
  #
208
216
  # :call-seq:
209
- # include?(key)
217
+ # include?(key)
210
218
  #
211
219
  # Returns true if the given key is present in the parameters.
212
220
 
@@ -214,7 +222,7 @@ module ActionController
214
222
  # :method: keys
215
223
  #
216
224
  # :call-seq:
217
- # keys()
225
+ # keys()
218
226
  #
219
227
  # Returns a new array of the keys of the parameters.
220
228
 
@@ -222,7 +230,7 @@ module ActionController
222
230
  # :method: to_s
223
231
  #
224
232
  # :call-seq:
225
- # to_s()
233
+ # to_s()
226
234
  #
227
235
  # Returns the content of the parameters as a string.
228
236
 
@@ -233,39 +241,50 @@ module ActionController
233
241
  alias_method :key?, :include?
234
242
  alias_method :member?, :include?
235
243
 
236
- # By default, never raise an UnpermittedParameters exception if these
237
- # params are present. The default includes both 'controller' and 'action'
238
- # because they are added by Rails and should be of no concern. One way
239
- # to change these is to specify +always_permitted_parameters+ in your
240
- # config. For instance:
244
+ # By default, never raise an UnpermittedParameters exception if these params are
245
+ # present. The default includes both 'controller' and 'action' because they are
246
+ # added by Rails and should be of no concern. One way to change these is to
247
+ # specify `always_permitted_parameters` in your config. For instance:
241
248
  #
242
- # config.action_controller.always_permitted_parameters = %w( controller action format )
249
+ # config.action_controller.always_permitted_parameters = %w( controller action format )
243
250
  cattr_accessor :always_permitted_parameters, default: %w( controller action )
244
251
 
245
- cattr_accessor :allow_deprecated_parameters_hash_equality, default: true, instance_accessor: false
246
-
247
252
  class << self
253
+ def allow_deprecated_parameters_hash_equality
254
+ ActionController.deprecator.warn <<-WARNING.squish
255
+ `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality` is
256
+ deprecated and will be removed in Rails 8.0.
257
+ WARNING
258
+ end
259
+
260
+ def allow_deprecated_parameters_hash_equality=(value)
261
+ ActionController.deprecator.warn <<-WARNING.squish
262
+ `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`
263
+ is deprecated and will be removed in Rails 8.0.
264
+ WARNING
265
+ end
266
+
248
267
  def nested_attribute?(key, value) # :nodoc:
249
268
  /\A-?\d+\z/.match?(key) && (value.is_a?(Hash) || value.is_a?(Parameters))
250
269
  end
251
270
  end
252
271
 
253
- # Returns a new +ActionController::Parameters+ instance.
254
- # Also, sets the +permitted+ attribute to the default value of
255
- # <tt>ActionController::Parameters.permit_all_parameters</tt>.
272
+ # Returns a new `ActionController::Parameters` instance. Also, sets the
273
+ # `permitted` attribute to the default value of
274
+ # `ActionController::Parameters.permit_all_parameters`.
256
275
  #
257
- # class Person < ActiveRecord::Base
258
- # end
276
+ # class Person < ActiveRecord::Base
277
+ # end
259
278
  #
260
- # params = ActionController::Parameters.new(name: "Francesco")
261
- # params.permitted? # => false
262
- # Person.new(params) # => ActiveModel::ForbiddenAttributesError
279
+ # params = ActionController::Parameters.new(name: "Francesco")
280
+ # params.permitted? # => false
281
+ # Person.new(params) # => ActiveModel::ForbiddenAttributesError
263
282
  #
264
- # ActionController::Parameters.permit_all_parameters = true
283
+ # ActionController::Parameters.permit_all_parameters = true
265
284
  #
266
- # params = ActionController::Parameters.new(name: "Francesco")
267
- # params.permitted? # => true
268
- # Person.new(params) # => #<Person id: nil, name: "Francesco">
285
+ # params = ActionController::Parameters.new(name: "Francesco")
286
+ # params.permitted? # => true
287
+ # Person.new(params) # => #<Person id: nil, name: "Francesco">
269
288
  def initialize(parameters = {}, logging_context = {})
270
289
  parameters.each_key do |key|
271
290
  unless key.is_a?(String) || key.is_a?(Symbol)
@@ -278,26 +297,13 @@ module ActionController
278
297
  @permitted = self.class.permit_all_parameters
279
298
  end
280
299
 
281
- # Returns true if another +Parameters+ object contains the same content and
300
+ # Returns true if another `Parameters` object contains the same content and
282
301
  # permitted flag.
283
302
  def ==(other)
284
303
  if other.respond_to?(:permitted?)
285
304
  permitted? == other.permitted? && parameters == other.parameters
286
305
  else
287
- if self.class.allow_deprecated_parameters_hash_equality && Hash === other
288
- ActionController.deprecator.warn <<-WARNING.squish
289
- Comparing equality between `ActionController::Parameters` and a
290
- `Hash` is deprecated and will be removed in Rails 7.2. Please only do
291
- comparisons between instances of `ActionController::Parameters`. If
292
- you need to compare to a hash, first convert it using
293
- `ActionController::Parameters#new`.
294
- To disable the deprecated behavior set
295
- `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false`.
296
- WARNING
297
- @parameters == other
298
- else
299
- super
300
- end
306
+ super
301
307
  end
302
308
  end
303
309
 
@@ -311,18 +317,18 @@ module ActionController
311
317
  [self.class, @parameters, @permitted].hash
312
318
  end
313
319
 
314
- # Returns a safe ActiveSupport::HashWithIndifferentAccess
315
- # representation of the parameters with all unpermitted keys removed.
320
+ # Returns a safe ActiveSupport::HashWithIndifferentAccess representation of the
321
+ # parameters with all unpermitted keys removed.
316
322
  #
317
- # params = ActionController::Parameters.new({
318
- # name: "Senjougahara Hitagi",
319
- # oddity: "Heavy stone crab"
320
- # })
321
- # params.to_h
322
- # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
323
+ # params = ActionController::Parameters.new({
324
+ # name: "Senjougahara Hitagi",
325
+ # oddity: "Heavy stone crab"
326
+ # })
327
+ # params.to_h
328
+ # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
323
329
  #
324
- # safe_params = params.permit(:name)
325
- # safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
330
+ # safe_params = params.permit(:name)
331
+ # safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
326
332
  def to_h(&block)
327
333
  if permitted?
328
334
  convert_parameters_to_hashes(@parameters, :to_h, &block)
@@ -331,18 +337,18 @@ module ActionController
331
337
  end
332
338
  end
333
339
 
334
- # Returns a safe <tt>Hash</tt> representation of the parameters
335
- # with all unpermitted keys removed.
340
+ # Returns a safe `Hash` representation of the parameters with all unpermitted
341
+ # keys removed.
336
342
  #
337
- # params = ActionController::Parameters.new({
338
- # name: "Senjougahara Hitagi",
339
- # oddity: "Heavy stone crab"
340
- # })
341
- # params.to_hash
342
- # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
343
+ # params = ActionController::Parameters.new({
344
+ # name: "Senjougahara Hitagi",
345
+ # oddity: "Heavy stone crab"
346
+ # })
347
+ # params.to_hash
348
+ # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
343
349
  #
344
- # safe_params = params.permit(:name)
345
- # safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
350
+ # safe_params = params.permit(:name)
351
+ # safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
346
352
  def to_hash
347
353
  to_h.to_hash
348
354
  end
@@ -350,29 +356,29 @@ module ActionController
350
356
  # Returns a string representation of the receiver suitable for use as a URL
351
357
  # query string:
352
358
  #
353
- # params = ActionController::Parameters.new({
354
- # name: "David",
355
- # nationality: "Danish"
356
- # })
357
- # params.to_query
358
- # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
359
+ # params = ActionController::Parameters.new({
360
+ # name: "David",
361
+ # nationality: "Danish"
362
+ # })
363
+ # params.to_query
364
+ # # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
359
365
  #
360
- # safe_params = params.permit(:name, :nationality)
361
- # safe_params.to_query
362
- # # => "name=David&nationality=Danish"
366
+ # safe_params = params.permit(:name, :nationality)
367
+ # safe_params.to_query
368
+ # # => "name=David&nationality=Danish"
363
369
  #
364
370
  # An optional namespace can be passed to enclose key names:
365
371
  #
366
- # params = ActionController::Parameters.new({
367
- # name: "David",
368
- # nationality: "Danish"
369
- # })
370
- # safe_params = params.permit(:name, :nationality)
371
- # safe_params.to_query("user")
372
- # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
372
+ # params = ActionController::Parameters.new({
373
+ # name: "David",
374
+ # nationality: "Danish"
375
+ # })
376
+ # safe_params = params.permit(:name, :nationality)
377
+ # safe_params.to_query("user")
378
+ # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
373
379
  #
374
- # The string pairs <tt>"key=value"</tt> that conform the query string
375
- # are sorted lexicographically in ascending order.
380
+ # The string pairs `"key=value"` that conform the query string are sorted
381
+ # lexicographically in ascending order.
376
382
  def to_query(*args)
377
383
  to_h.to_query(*args)
378
384
  end
@@ -381,19 +387,19 @@ module ActionController
381
387
  # Returns an unsafe, unfiltered ActiveSupport::HashWithIndifferentAccess
382
388
  # representation of the parameters.
383
389
  #
384
- # params = ActionController::Parameters.new({
385
- # name: "Senjougahara Hitagi",
386
- # oddity: "Heavy stone crab"
387
- # })
388
- # params.to_unsafe_h
389
- # # => {"name"=>"Senjougahara Hitagi", "oddity" => "Heavy stone crab"}
390
+ # params = ActionController::Parameters.new({
391
+ # name: "Senjougahara Hitagi",
392
+ # oddity: "Heavy stone crab"
393
+ # })
394
+ # params.to_unsafe_h
395
+ # # => {"name"=>"Senjougahara Hitagi", "oddity" => "Heavy stone crab"}
390
396
  def to_unsafe_h
391
397
  convert_parameters_to_hashes(@parameters, :to_unsafe_h)
392
398
  end
393
399
  alias_method :to_unsafe_hash, :to_unsafe_h
394
400
 
395
- # Convert all hashes in values into parameters, then yield each pair in
396
- # the same way as <tt>Hash#each_pair</tt>.
401
+ # Convert all hashes in values into parameters, then yield each pair in the same
402
+ # way as `Hash#each_pair`.
397
403
  def each_pair(&block)
398
404
  return to_enum(__callee__) unless block_given?
399
405
  @parameters.each_pair do |key, value|
@@ -404,8 +410,8 @@ module ActionController
404
410
  end
405
411
  alias_method :each, :each_pair
406
412
 
407
- # Convert all hashes in values into parameters, then yield each value in
408
- # the same way as <tt>Hash#each_value</tt>.
413
+ # Convert all hashes in values into parameters, then yield each value in the
414
+ # same way as `Hash#each_value`.
409
415
  def each_value(&block)
410
416
  return to_enum(:each_value) unless block_given?
411
417
  @parameters.each_pair do |key, value|
@@ -421,38 +427,38 @@ module ActionController
421
427
  end
422
428
 
423
429
  # Attribute that keeps track of converted arrays, if any, to avoid double
424
- # looping in the common use case permit + mass-assignment. Defined in a
425
- # method to instantiate it only if needed.
430
+ # looping in the common use case permit + mass-assignment. Defined in a method
431
+ # to instantiate it only if needed.
426
432
  #
427
- # \Testing membership still loops, but it's going to be faster than our own
428
- # loop that converts values. Also, we are not going to build a new array
429
- # object per fetch.
433
+ # Testing membership still loops, but it's going to be faster than our own loop
434
+ # that converts values. Also, we are not going to build a new array object per
435
+ # fetch.
430
436
  def converted_arrays
431
437
  @converted_arrays ||= Set.new
432
438
  end
433
439
 
434
- # Returns +true+ if the parameter is permitted, +false+ otherwise.
440
+ # Returns `true` if the parameter is permitted, `false` otherwise.
435
441
  #
436
- # params = ActionController::Parameters.new
437
- # params.permitted? # => false
438
- # params.permit!
439
- # params.permitted? # => true
442
+ # params = ActionController::Parameters.new
443
+ # params.permitted? # => false
444
+ # params.permit!
445
+ # params.permitted? # => true
440
446
  def permitted?
441
447
  @permitted
442
448
  end
443
449
 
444
- # Sets the +permitted+ attribute to +true+. This can be used to pass
445
- # mass assignment. Returns +self+.
450
+ # Sets the `permitted` attribute to `true`. This can be used to pass mass
451
+ # assignment. Returns `self`.
446
452
  #
447
- # class Person < ActiveRecord::Base
448
- # end
453
+ # class Person < ActiveRecord::Base
454
+ # end
449
455
  #
450
- # params = ActionController::Parameters.new(name: "Francesco")
451
- # params.permitted? # => false
452
- # Person.new(params) # => ActiveModel::ForbiddenAttributesError
453
- # params.permit!
454
- # params.permitted? # => true
455
- # Person.new(params) # => #<Person id: nil, name: "Francesco">
456
+ # params = ActionController::Parameters.new(name: "Francesco")
457
+ # params.permitted? # => false
458
+ # Person.new(params) # => ActiveModel::ForbiddenAttributesError
459
+ # params.permit!
460
+ # params.permitted? # => true
461
+ # Person.new(params) # => #<Person id: nil, name: "Francesco">
456
462
  def permit!
457
463
  each_pair do |key, value|
458
464
  Array.wrap(value).flatten.each do |v|
@@ -466,52 +472,51 @@ module ActionController
466
472
 
467
473
  # This method accepts both a single key and an array of keys.
468
474
  #
469
- # When passed a single key, if it exists and its associated value is
470
- # either present or the singleton +false+, returns said value:
475
+ # When passed a single key, if it exists and its associated value is either
476
+ # present or the singleton `false`, returns said value:
471
477
  #
472
- # ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
473
- # # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
478
+ # ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
479
+ # # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
474
480
  #
475
481
  # Otherwise raises ActionController::ParameterMissing:
476
482
  #
477
- # ActionController::Parameters.new.require(:person)
478
- # # ActionController::ParameterMissing: param is missing or the value is empty: person
483
+ # ActionController::Parameters.new.require(:person)
484
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
479
485
  #
480
- # ActionController::Parameters.new(person: nil).require(:person)
481
- # # ActionController::ParameterMissing: param is missing or the value is empty: person
486
+ # ActionController::Parameters.new(person: nil).require(:person)
487
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
482
488
  #
483
- # ActionController::Parameters.new(person: "\t").require(:person)
484
- # # ActionController::ParameterMissing: param is missing or the value is empty: person
489
+ # ActionController::Parameters.new(person: "\t").require(:person)
490
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
485
491
  #
486
- # ActionController::Parameters.new(person: {}).require(:person)
487
- # # ActionController::ParameterMissing: param is missing or the value is empty: person
492
+ # ActionController::Parameters.new(person: {}).require(:person)
493
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
488
494
  #
489
- # When given an array of keys, the method tries to require each one of them
490
- # in order. If it succeeds, an array with the respective return values is
491
- # returned:
495
+ # When given an array of keys, the method tries to require each one of them in
496
+ # order. If it succeeds, an array with the respective return values is returned:
492
497
  #
493
- # params = ActionController::Parameters.new(user: { ... }, profile: { ... })
494
- # user_params, profile_params = params.require([:user, :profile])
498
+ # params = ActionController::Parameters.new(user: { ... }, profile: { ... })
499
+ # user_params, profile_params = params.require([:user, :profile])
495
500
  #
496
501
  # Otherwise, the method re-raises the first exception found:
497
502
  #
498
- # params = ActionController::Parameters.new(user: {}, profile: {})
499
- # user_params, profile_params = params.require([:user, :profile])
500
- # # ActionController::ParameterMissing: param is missing or the value is empty: user
503
+ # params = ActionController::Parameters.new(user: {}, profile: {})
504
+ # user_params, profile_params = params.require([:user, :profile])
505
+ # # ActionController::ParameterMissing: param is missing or the value is empty: user
501
506
  #
502
507
  # Technically this method can be used to fetch terminal values:
503
508
  #
504
- # # CAREFUL
505
- # params = ActionController::Parameters.new(person: { name: "Finn" })
506
- # name = params.require(:person).require(:name) # CAREFUL
509
+ # # CAREFUL
510
+ # params = ActionController::Parameters.new(person: { name: "Finn" })
511
+ # name = params.require(:person).require(:name) # CAREFUL
507
512
  #
508
513
  # but take into account that at some point those ones have to be permitted:
509
514
  #
510
- # def person_params
511
- # params.require(:person).permit(:name).tap do |person_params|
512
- # person_params.require(:name) # SAFER
515
+ # def person_params
516
+ # params.require(:person).permit(:name).tap do |person_params|
517
+ # person_params.require(:name) # SAFER
518
+ # end
513
519
  # end
514
- # end
515
520
  #
516
521
  # for example.
517
522
  def require(key)
@@ -526,119 +531,120 @@ module ActionController
526
531
 
527
532
  alias :required :require
528
533
 
529
- # Returns a new +ActionController::Parameters+ instance that
530
- # includes only the given +filters+ and sets the +permitted+ attribute
531
- # for the object to +true+. This is useful for limiting which attributes
532
- # should be allowed for mass updating.
534
+ # Returns a new `ActionController::Parameters` instance that includes only the
535
+ # given `filters` and sets the `permitted` attribute for the object to `true`.
536
+ # This is useful for limiting which attributes should be allowed for mass
537
+ # updating.
533
538
  #
534
- # params = ActionController::Parameters.new(user: { name: "Francesco", age: 22, role: "admin" })
535
- # permitted = params.require(:user).permit(:name, :age)
536
- # permitted.permitted? # => true
537
- # permitted.has_key?(:name) # => true
538
- # permitted.has_key?(:age) # => true
539
- # permitted.has_key?(:role) # => false
539
+ # params = ActionController::Parameters.new(user: { name: "Francesco", age: 22, role: "admin" })
540
+ # permitted = params.require(:user).permit(:name, :age)
541
+ # permitted.permitted? # => true
542
+ # permitted.has_key?(:name) # => true
543
+ # permitted.has_key?(:age) # => true
544
+ # permitted.has_key?(:role) # => false
540
545
  #
541
546
  # Only permitted scalars pass the filter. For example, given
542
547
  #
543
- # params.permit(:name)
544
- #
545
- # +:name+ passes if it is a key of +params+ whose associated value is of type
546
- # +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+,
547
- # +Date+, +Time+, +DateTime+, +StringIO+, +IO+,
548
- # ActionDispatch::Http::UploadedFile or +Rack::Test::UploadedFile+.
549
- # Otherwise, the key +:name+ is filtered out.
550
- #
551
- # You may declare that the parameter should be an array of permitted scalars
552
- # by mapping it to an empty array:
553
- #
554
- # params = ActionController::Parameters.new(tags: ["rails", "parameters"])
555
- # params.permit(tags: [])
556
- #
557
- # Sometimes it is not possible or convenient to declare the valid keys of
558
- # a hash parameter or its internal structure. Just map to an empty hash:
559
- #
560
- # params.permit(preferences: {})
561
- #
562
- # Be careful because this opens the door to arbitrary input. In this
563
- # case, +permit+ ensures values in the returned structure are permitted
564
- # scalars and filters out anything else.
565
- #
566
- # You can also use +permit+ on nested parameters, like:
567
- #
568
- # params = ActionController::Parameters.new({
569
- # person: {
570
- # name: "Francesco",
571
- # age: 22,
572
- # pets: [{
573
- # name: "Purplish",
574
- # category: "dogs"
575
- # }]
576
- # }
577
- # })
578
- #
579
- # permitted = params.permit(person: [ :name, { pets: :name } ])
580
- # permitted.permitted? # => true
581
- # permitted[:person][:name] # => "Francesco"
582
- # permitted[:person][:age] # => nil
583
- # permitted[:person][:pets][0][:name] # => "Purplish"
584
- # permitted[:person][:pets][0][:category] # => nil
585
- #
586
- # Note that if you use +permit+ in a key that points to a hash,
587
- # it won't allow all the hash. You also need to specify which
588
- # attributes inside the hash should be permitted.
589
- #
590
- # params = ActionController::Parameters.new({
591
- # person: {
592
- # contact: {
593
- # email: "none@test.com",
594
- # phone: "555-1234"
548
+ # params.permit(:name)
549
+ #
550
+ # `:name` passes if it is a key of `params` whose associated value is of type
551
+ # `String`, `Symbol`, `NilClass`, `Numeric`, `TrueClass`, `FalseClass`, `Date`,
552
+ # `Time`, `DateTime`, `StringIO`, `IO`, ActionDispatch::Http::UploadedFile or
553
+ # `Rack::Test::UploadedFile`. Otherwise, the key `:name` is filtered out.
554
+ #
555
+ # You may declare that the parameter should be an array of permitted scalars by
556
+ # mapping it to an empty array:
557
+ #
558
+ # params = ActionController::Parameters.new(tags: ["rails", "parameters"])
559
+ # params.permit(tags: [])
560
+ #
561
+ # Sometimes it is not possible or convenient to declare the valid keys of a hash
562
+ # parameter or its internal structure. Just map to an empty hash:
563
+ #
564
+ # params.permit(preferences: {})
565
+ #
566
+ # Be careful because this opens the door to arbitrary input. In this case,
567
+ # `permit` ensures values in the returned structure are permitted scalars and
568
+ # filters out anything else.
569
+ #
570
+ # You can also use `permit` on nested parameters, like:
571
+ #
572
+ # params = ActionController::Parameters.new({
573
+ # person: {
574
+ # name: "Francesco",
575
+ # age: 22,
576
+ # pets: [{
577
+ # name: "Purplish",
578
+ # category: "dogs"
579
+ # }]
595
580
  # }
596
- # }
597
- # })
598
- #
599
- # params.require(:person).permit(:contact)
600
- # # => #<ActionController::Parameters {} permitted: true>
601
- #
602
- # params.require(:person).permit(contact: :phone)
603
- # # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
604
- #
605
- # params.require(:person).permit(contact: [ :email, :phone ])
606
- # # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
607
- #
608
- # If your parameters specify multiple parameters indexed by a number,
609
- # you can permit each set of parameters under the numeric key to be the same using the same syntax as permitting a single item.
610
- #
611
- # params = ActionController::Parameters.new({
612
- # person: {
613
- # '0': {
614
- # email: "none@test.com",
615
- # phone: "555-1234"
616
- # },
617
- # '1': {
618
- # email: "nothing@test.com",
619
- # phone: "555-6789"
620
- # },
621
- # }
622
- # })
623
- # params.permit(person: [:email]).to_h
624
- # # => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"email"=>"nothing@test.com"}}}
625
- #
626
- # If you want to specify what keys you want from each numeric key, you can instead specify each one individually
627
- #
628
- # params = ActionController::Parameters.new({
629
- # person: {
630
- # '0': {
631
- # email: "none@test.com",
632
- # phone: "555-1234"
633
- # },
634
- # '1': {
635
- # email: "nothing@test.com",
636
- # phone: "555-6789"
637
- # },
638
- # }
639
- # })
640
- # params.permit(person: { '0': [:email], '1': [:phone]}).to_h
641
- # # => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"phone"=>"555-6789"}}}
581
+ # })
582
+ #
583
+ # permitted = params.permit(person: [ :name, { pets: :name } ])
584
+ # permitted.permitted? # => true
585
+ # permitted[:person][:name] # => "Francesco"
586
+ # permitted[:person][:age] # => nil
587
+ # permitted[:person][:pets][0][:name] # => "Purplish"
588
+ # permitted[:person][:pets][0][:category] # => nil
589
+ #
590
+ # Note that if you use `permit` in a key that points to a hash, it won't allow
591
+ # all the hash. You also need to specify which attributes inside the hash should
592
+ # be permitted.
593
+ #
594
+ # params = ActionController::Parameters.new({
595
+ # person: {
596
+ # contact: {
597
+ # email: "none@test.com",
598
+ # phone: "555-1234"
599
+ # }
600
+ # }
601
+ # })
602
+ #
603
+ # params.require(:person).permit(:contact)
604
+ # # => #<ActionController::Parameters {} permitted: true>
605
+ #
606
+ # params.require(:person).permit(contact: :phone)
607
+ # # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
608
+ #
609
+ # params.require(:person).permit(contact: [ :email, :phone ])
610
+ # # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
611
+ #
612
+ # If your parameters specify multiple parameters indexed by a number, you can
613
+ # permit each set of parameters under the numeric key to be the same using the
614
+ # same syntax as permitting a single item.
615
+ #
616
+ # params = ActionController::Parameters.new({
617
+ # person: {
618
+ # '0': {
619
+ # email: "none@test.com",
620
+ # phone: "555-1234"
621
+ # },
622
+ # '1': {
623
+ # email: "nothing@test.com",
624
+ # phone: "555-6789"
625
+ # },
626
+ # }
627
+ # })
628
+ # params.permit(person: [:email]).to_h
629
+ # # => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"email"=>"nothing@test.com"}}}
630
+ #
631
+ # If you want to specify what keys you want from each numeric key, you can
632
+ # instead specify each one individually
633
+ #
634
+ # params = ActionController::Parameters.new({
635
+ # person: {
636
+ # '0': {
637
+ # email: "none@test.com",
638
+ # phone: "555-1234"
639
+ # },
640
+ # '1': {
641
+ # email: "nothing@test.com",
642
+ # phone: "555-6789"
643
+ # },
644
+ # }
645
+ # })
646
+ # params.permit(person: { '0': [:email], '1': [:phone]}).to_h
647
+ # # => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"phone"=>"555-6789"}}}
642
648
  def permit(*filters)
643
649
  params = self.class.new
644
650
 
@@ -656,35 +662,34 @@ module ActionController
656
662
  params.permit!
657
663
  end
658
664
 
659
- # Returns a parameter for the given +key+. If not found,
660
- # returns +nil+.
665
+ # Returns a parameter for the given `key`. If not found, returns `nil`.
661
666
  #
662
- # params = ActionController::Parameters.new(person: { name: "Francesco" })
663
- # params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
664
- # params[:none] # => nil
667
+ # params = ActionController::Parameters.new(person: { name: "Francesco" })
668
+ # params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
669
+ # params[:none] # => nil
665
670
  def [](key)
666
671
  convert_hashes_to_parameters(key, @parameters[key])
667
672
  end
668
673
 
669
- # Assigns a value to a given +key+. The given key may still get filtered out
674
+ # Assigns a value to a given `key`. The given key may still get filtered out
670
675
  # when #permit is called.
671
676
  def []=(key, value)
672
677
  @parameters[key] = value
673
678
  end
674
679
 
675
- # Returns a parameter for the given +key+. If the +key+
676
- # can't be found, there are several options: With no other arguments,
677
- # it will raise an ActionController::ParameterMissing error;
678
- # if a second argument is given, then that is returned (converted to an
679
- # instance of +ActionController::Parameters+ if possible); if a block
680
- # is given, then that will be run and its result returned.
681
- #
682
- # params = ActionController::Parameters.new(person: { name: "Francesco" })
683
- # params.fetch(:person) # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
684
- # params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none
685
- # params.fetch(:none, {}) # => #<ActionController::Parameters {} permitted: false>
686
- # params.fetch(:none, "Francesco") # => "Francesco"
687
- # params.fetch(:none) { "Francesco" } # => "Francesco"
680
+ # Returns a parameter for the given `key`. If the `key` can't be found, there
681
+ # are several options: With no other arguments, it will raise an
682
+ # ActionController::ParameterMissing error; if a second argument is given, then
683
+ # that is returned (converted to an instance of `ActionController::Parameters`
684
+ # if possible); if a block is given, then that will be run and its result
685
+ # returned.
686
+ #
687
+ # params = ActionController::Parameters.new(person: { name: "Francesco" })
688
+ # params.fetch(:person) # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
689
+ # params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none
690
+ # params.fetch(:none, {}) # => #<ActionController::Parameters {} permitted: false>
691
+ # params.fetch(:none, "Francesco") # => "Francesco"
692
+ # params.fetch(:none) { "Francesco" } # => "Francesco"
688
693
  def fetch(key, *args)
689
694
  convert_value_to_parameters(
690
695
  @parameters.fetch(key) {
@@ -697,44 +702,43 @@ module ActionController
697
702
  )
698
703
  end
699
704
 
700
- # Extracts the nested parameter from the given +keys+ by calling +dig+
701
- # at each step. Returns +nil+ if any intermediate step is +nil+.
705
+ # Extracts the nested parameter from the given `keys` by calling `dig` at each
706
+ # step. Returns `nil` if any intermediate step is `nil`.
702
707
  #
703
- # params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
704
- # params.dig(:foo, :bar, :baz) # => 1
705
- # params.dig(:foo, :zot, :xyz) # => nil
708
+ # params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
709
+ # params.dig(:foo, :bar, :baz) # => 1
710
+ # params.dig(:foo, :zot, :xyz) # => nil
706
711
  #
707
- # params2 = ActionController::Parameters.new(foo: [10, 11, 12])
708
- # params2.dig(:foo, 1) # => 11
712
+ # params2 = ActionController::Parameters.new(foo: [10, 11, 12])
713
+ # params2.dig(:foo, 1) # => 11
709
714
  def dig(*keys)
710
715
  convert_hashes_to_parameters(keys.first, @parameters[keys.first])
711
716
  @parameters.dig(*keys)
712
717
  end
713
718
 
714
- # Returns a new +ActionController::Parameters+ instance that
715
- # includes only the given +keys+. If the given +keys+
716
- # don't exist, returns an empty hash.
719
+ # Returns a new `ActionController::Parameters` instance that includes only the
720
+ # given `keys`. If the given `keys` don't exist, returns an empty hash.
717
721
  #
718
- # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
719
- # params.slice(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
720
- # params.slice(:d) # => #<ActionController::Parameters {} permitted: false>
722
+ # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
723
+ # params.slice(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
724
+ # params.slice(:d) # => #<ActionController::Parameters {} permitted: false>
721
725
  def slice(*keys)
722
726
  new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
723
727
  end
724
728
 
725
- # Returns the current +ActionController::Parameters+ instance which
726
- # contains only the given +keys+.
729
+ # Returns the current `ActionController::Parameters` instance which contains
730
+ # only the given `keys`.
727
731
  def slice!(*keys)
728
732
  @parameters.slice!(*keys)
729
733
  self
730
734
  end
731
735
 
732
- # Returns a new +ActionController::Parameters+ instance that
733
- # filters out the given +keys+.
736
+ # Returns a new `ActionController::Parameters` instance that filters out the
737
+ # given `keys`.
734
738
  #
735
- # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
736
- # params.except(:a, :b) # => #<ActionController::Parameters {"c"=>3} permitted: false>
737
- # params.except(:d) # => #<ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
739
+ # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
740
+ # params.except(:a, :b) # => #<ActionController::Parameters {"c"=>3} permitted: false>
741
+ # params.except(:d) # => #<ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
738
742
  def except(*keys)
739
743
  new_instance_with_inherited_permitted_status(@parameters.except(*keys))
740
744
  end
@@ -742,19 +746,19 @@ module ActionController
742
746
 
743
747
  # Removes and returns the key/value pairs matching the given keys.
744
748
  #
745
- # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
746
- # params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
747
- # params # => #<ActionController::Parameters {"c"=>3} permitted: false>
749
+ # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
750
+ # params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
751
+ # params # => #<ActionController::Parameters {"c"=>3} permitted: false>
748
752
  def extract!(*keys)
749
753
  new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
750
754
  end
751
755
 
752
- # Returns a new +ActionController::Parameters+ instance with the results of
753
- # running +block+ once for every value. The keys are unchanged.
756
+ # Returns a new `ActionController::Parameters` instance with the results of
757
+ # running `block` once for every value. The keys are unchanged.
754
758
  #
755
- # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
756
- # params.transform_values { |x| x * 2 }
757
- # # => #<ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
759
+ # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
760
+ # params.transform_values { |x| x * 2 }
761
+ # # => #<ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
758
762
  def transform_values
759
763
  return to_enum(:transform_values) unless block_given?
760
764
  new_instance_with_inherited_permitted_status(
@@ -763,15 +767,15 @@ module ActionController
763
767
  end
764
768
 
765
769
  # Performs values transformation and returns the altered
766
- # +ActionController::Parameters+ instance.
770
+ # `ActionController::Parameters` instance.
767
771
  def transform_values!
768
772
  return to_enum(:transform_values!) unless block_given?
769
773
  @parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
770
774
  self
771
775
  end
772
776
 
773
- # Returns a new +ActionController::Parameters+ instance with the
774
- # results of running +block+ once for every key. The values are unchanged.
777
+ # Returns a new `ActionController::Parameters` instance with the results of
778
+ # running `block` once for every key. The values are unchanged.
775
779
  def transform_keys(&block)
776
780
  return to_enum(:transform_keys) unless block_given?
777
781
  new_instance_with_inherited_permitted_status(
@@ -780,53 +784,53 @@ module ActionController
780
784
  end
781
785
 
782
786
  # Performs keys transformation and returns the altered
783
- # +ActionController::Parameters+ instance.
787
+ # `ActionController::Parameters` instance.
784
788
  def transform_keys!(&block)
785
789
  return to_enum(:transform_keys!) unless block_given?
786
790
  @parameters.transform_keys!(&block)
787
791
  self
788
792
  end
789
793
 
790
- # Returns a new +ActionController::Parameters+ instance with the
791
- # results of running +block+ once for every key. This includes the keys
792
- # from the root hash and from all nested hashes and arrays. The values are unchanged.
794
+ # Returns a new `ActionController::Parameters` instance with the results of
795
+ # running `block` once for every key. This includes the keys from the root hash
796
+ # and from all nested hashes and arrays. The values are unchanged.
793
797
  def deep_transform_keys(&block)
794
798
  new_instance_with_inherited_permitted_status(
795
- @parameters.deep_transform_keys(&block)
799
+ _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
796
800
  )
797
801
  end
798
802
 
799
- # Returns the same +ActionController::Parameters+ instance with
800
- # changed keys. This includes the keys from the root hash and from all
801
- # nested hashes and arrays. The values are unchanged.
803
+ # Returns the same `ActionController::Parameters` instance with changed keys.
804
+ # This includes the keys from the root hash and from all nested hashes and
805
+ # arrays. The values are unchanged.
802
806
  def deep_transform_keys!(&block)
803
- @parameters.deep_transform_keys!(&block)
807
+ @parameters = _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
804
808
  self
805
809
  end
806
810
 
807
- # Deletes a key-value pair from +Parameters+ and returns the value. If
808
- # +key+ is not found, returns +nil+ (or, with optional code block, yields
809
- # +key+ and returns the result). This method is similar to #extract!, which
810
- # returns the corresponding +ActionController::Parameters+ object.
811
+ # Deletes a key-value pair from `Parameters` and returns the value. If `key` is
812
+ # not found, returns `nil` (or, with optional code block, yields `key` and
813
+ # returns the result). This method is similar to #extract!, which returns the
814
+ # corresponding `ActionController::Parameters` object.
811
815
  def delete(key, &block)
812
816
  convert_value_to_parameters(@parameters.delete(key, &block))
813
817
  end
814
818
 
815
- # Returns a new +ActionController::Parameters+ instance with only
816
- # items that the block evaluates to true.
819
+ # Returns a new `ActionController::Parameters` instance with only items that the
820
+ # block evaluates to true.
817
821
  def select(&block)
818
822
  new_instance_with_inherited_permitted_status(@parameters.select(&block))
819
823
  end
820
824
 
821
- # Equivalent to Hash#keep_if, but returns +nil+ if no changes were made.
825
+ # Equivalent to Hash#keep_if, but returns `nil` if no changes were made.
822
826
  def select!(&block)
823
827
  @parameters.select!(&block)
824
828
  self
825
829
  end
826
830
  alias_method :keep_if, :select!
827
831
 
828
- # Returns a new +ActionController::Parameters+ instance with items
829
- # that the block evaluates to true removed.
832
+ # Returns a new `ActionController::Parameters` instance with items that the
833
+ # block evaluates to true removed.
830
834
  def reject(&block)
831
835
  new_instance_with_inherited_permitted_status(@parameters.reject(&block))
832
836
  end
@@ -838,24 +842,26 @@ module ActionController
838
842
  end
839
843
  alias_method :delete_if, :reject!
840
844
 
841
- # Returns a new +ActionController::Parameters+ instance with +nil+ values removed.
845
+ # Returns a new `ActionController::Parameters` instance with `nil` values
846
+ # removed.
842
847
  def compact
843
848
  new_instance_with_inherited_permitted_status(@parameters.compact)
844
849
  end
845
850
 
846
- # Removes all +nil+ values in place and returns +self+, or +nil+ if no changes were made.
851
+ # Removes all `nil` values in place and returns `self`, or `nil` if no changes
852
+ # were made.
847
853
  def compact!
848
854
  self if @parameters.compact!
849
855
  end
850
856
 
851
- # Returns a new +ActionController::Parameters+ instance without the blank values.
852
- # Uses Object#blank? for determining if a value is blank.
857
+ # Returns a new `ActionController::Parameters` instance without the blank
858
+ # values. Uses Object#blank? for determining if a value is blank.
853
859
  def compact_blank
854
860
  reject { |_k, v| v.blank? }
855
861
  end
856
862
 
857
- # Removes all blank values in place and returns self.
858
- # Uses Object#blank? for determining if a value is blank.
863
+ # Removes all blank values in place and returns self. Uses Object#blank? for
864
+ # determining if a value is blank.
859
865
  def compact_blank!
860
866
  reject! { |_k, v| v.blank? }
861
867
  end
@@ -867,14 +873,14 @@ module ActionController
867
873
 
868
874
  alias value? has_value?
869
875
 
870
- # Returns values that were assigned to the given +keys+. Note that all the
871
- # +Hash+ objects will be converted to +ActionController::Parameters+.
876
+ # Returns values that were assigned to the given `keys`. Note that all the
877
+ # `Hash` objects will be converted to `ActionController::Parameters`.
872
878
  def values_at(*keys)
873
879
  convert_value_to_parameters(@parameters.values_at(*keys))
874
880
  end
875
881
 
876
- # Returns a new +ActionController::Parameters+ instance with all keys from
877
- # +other_hash+ merged into current hash.
882
+ # Returns a new `ActionController::Parameters` instance with all keys from
883
+ # `other_hash` merged into current hash.
878
884
  def merge(other_hash)
879
885
  new_instance_with_inherited_permitted_status(
880
886
  @parameters.merge(other_hash.to_h)
@@ -884,8 +890,8 @@ module ActionController
884
890
  ##
885
891
  # :call-seq: merge!(other_hash)
886
892
  #
887
- # Returns the current +ActionController::Parameters+ instance with
888
- # +other_hash+ merged into current hash.
893
+ # Returns the current `ActionController::Parameters` instance with `other_hash`
894
+ # merged into current hash.
889
895
  def merge!(other_hash, &block)
890
896
  @parameters.merge!(other_hash.to_h, &block)
891
897
  self
@@ -895,8 +901,8 @@ module ActionController
895
901
  other_hash.is_a?(ActiveSupport::DeepMergeable)
896
902
  end
897
903
 
898
- # Returns a new +ActionController::Parameters+ instance with all keys
899
- # from current hash merged into +other_hash+.
904
+ # Returns a new `ActionController::Parameters` instance with all keys from
905
+ # current hash merged into `other_hash`.
900
906
  def reverse_merge(other_hash)
901
907
  new_instance_with_inherited_permitted_status(
902
908
  other_hash.to_h.merge(@parameters)
@@ -904,17 +910,17 @@ module ActionController
904
910
  end
905
911
  alias_method :with_defaults, :reverse_merge
906
912
 
907
- # Returns the current +ActionController::Parameters+ instance with
908
- # current hash merged into +other_hash+.
913
+ # Returns the current `ActionController::Parameters` instance with current hash
914
+ # merged into `other_hash`.
909
915
  def reverse_merge!(other_hash)
910
916
  @parameters.merge!(other_hash.to_h) { |key, left, right| left }
911
917
  self
912
918
  end
913
919
  alias_method :with_defaults!, :reverse_merge!
914
920
 
915
- # This is required by ActiveModel attribute assignment, so that user can
916
- # pass +Parameters+ to a mass assignment methods in a model. It should not
917
- # matter as we are using +HashWithIndifferentAccess+ internally.
921
+ # This is required by ActiveModel attribute assignment, so that user can pass
922
+ # `Parameters` to a mass assignment methods in a model. It should not matter as
923
+ # we are using `HashWithIndifferentAccess` internally.
918
924
  def stringify_keys # :nodoc:
919
925
  dup
920
926
  end
@@ -939,13 +945,13 @@ module ActionController
939
945
  @parameters = coder.map.with_indifferent_access
940
946
  @permitted = false
941
947
  when "!ruby/hash-with-ivars:ActionController::Parameters"
942
- # YAML 2.0.9's Hash subclass format where keys and values
943
- # were stored under an elements hash and `permitted` within an ivars hash.
948
+ # YAML 2.0.9's Hash subclass format where keys and values were stored under an
949
+ # elements hash and `permitted` within an ivars hash.
944
950
  @parameters = coder.map["elements"].with_indifferent_access
945
951
  @permitted = coder.map["ivars"][:@permitted]
946
952
  when "!ruby/object:ActionController::Parameters"
947
- # YAML's Object format. Only needed because of the format
948
- # backwards compatibility above, otherwise equivalent to YAML's initialization.
953
+ # YAML's Object format. Only needed because of the format backwards
954
+ # compatibility above, otherwise equivalent to YAML's initialization.
949
955
  @parameters, @permitted = coder.map["parameters"], coder.map["permitted"]
950
956
  end
951
957
  end
@@ -954,25 +960,26 @@ module ActionController
954
960
  coder.map = { "parameters" => @parameters, "permitted" => @permitted }
955
961
  end
956
962
 
957
- # Returns a duplicate +ActionController::Parameters+ instance with the same permitted parameters.
963
+ # Returns a duplicate `ActionController::Parameters` instance with the same
964
+ # permitted parameters.
958
965
  def deep_dup
959
966
  self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
960
967
  duplicate.permitted = @permitted
961
968
  end
962
969
  end
963
970
 
964
- # Returns parameter value for the given +key+ separated by +delimiter+.
971
+ # Returns parameter value for the given `key` separated by `delimiter`.
965
972
  #
966
- # params = ActionController::Parameters.new(id: "1_123", tags: "ruby,rails")
967
- # params.extract_value(:id) # => ["1", "123"]
968
- # params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails"]
969
- # params.extract_value(:non_existent_key) # => nil
973
+ # params = ActionController::Parameters.new(id: "1_123", tags: "ruby,rails")
974
+ # params.extract_value(:id) # => ["1", "123"]
975
+ # params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails"]
976
+ # params.extract_value(:non_existent_key) # => nil
970
977
  #
971
- # Note that if the given +key+'s value contains blank elements, then
972
- # the returned array will include empty strings.
978
+ # Note that if the given `key`'s value contains blank elements, then the
979
+ # returned array will include empty strings.
973
980
  #
974
- # params = ActionController::Parameters.new(tags: "ruby,rails,,web")
975
- # params.extract_value(:tags) # => ["ruby", "rails", "", "web"]
981
+ # params = ActionController::Parameters.new(tags: "ruby,rails,,web")
982
+ # params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails", "", "web"]
976
983
  def extract_value(key, delimiter: "_")
977
984
  @parameters[key]&.split(delimiter, -1)
978
985
  end
@@ -1035,6 +1042,46 @@ module ActionController
1035
1042
  end
1036
1043
  end
1037
1044
 
1045
+ def _deep_transform_keys_in_object(object, &block)
1046
+ case object
1047
+ when Hash
1048
+ object.each_with_object(self.class.new) do |(key, value), result|
1049
+ result[yield(key)] = _deep_transform_keys_in_object(value, &block)
1050
+ end
1051
+ when Parameters
1052
+ if object.permitted?
1053
+ object.to_h.deep_transform_keys(&block)
1054
+ else
1055
+ object.to_unsafe_h.deep_transform_keys(&block)
1056
+ end
1057
+ when Array
1058
+ object.map { |e| _deep_transform_keys_in_object(e, &block) }
1059
+ else
1060
+ object
1061
+ end
1062
+ end
1063
+
1064
+ def _deep_transform_keys_in_object!(object, &block)
1065
+ case object
1066
+ when Hash
1067
+ object.keys.each do |key|
1068
+ value = object.delete(key)
1069
+ object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
1070
+ end
1071
+ object
1072
+ when Parameters
1073
+ if object.permitted?
1074
+ object.to_h.deep_transform_keys!(&block)
1075
+ else
1076
+ object.to_unsafe_h.deep_transform_keys!(&block)
1077
+ end
1078
+ when Array
1079
+ object.map! { |e| _deep_transform_keys_in_object!(e, &block) }
1080
+ else
1081
+ object
1082
+ end
1083
+ end
1084
+
1038
1085
  def specify_numeric_keys?(filter)
1039
1086
  if filter.respond_to?(:keys)
1040
1087
  filter.keys.any? { |key| /\A-?\d+\z/.match?(key) }
@@ -1074,15 +1121,14 @@ module ActionController
1074
1121
  #
1075
1122
  # --- Filtering ----------------------------------------------------------
1076
1123
  #
1077
-
1078
- # This is a list of permitted scalar types that includes the ones
1079
- # supported in XML and JSON requests.
1124
+ # This is a list of permitted scalar types that includes the ones supported in
1125
+ # XML and JSON requests.
1080
1126
  #
1081
- # This list is in particular used to filter ordinary requests, \String goes
1082
- # as first element to quickly short-circuit the common case.
1127
+ # This list is in particular used to filter ordinary requests, String goes as
1128
+ # first element to quickly short-circuit the common case.
1083
1129
  #
1084
- # If you modify this collection please update the one in the #permit doc
1085
- # as well.
1130
+ # If you modify this collection please update the one in the #permit doc as
1131
+ # well.
1086
1132
  PERMITTED_SCALAR_TYPES = [
1087
1133
  String,
1088
1134
  Symbol,
@@ -1107,12 +1153,12 @@ module ActionController
1107
1153
  #
1108
1154
  # For example:
1109
1155
  #
1110
- # puts self.keys #=> ["zipcode(90210i)"]
1111
- # params = {}
1156
+ # puts self.keys #=> ["zipcode(90210i)"]
1157
+ # params = {}
1112
1158
  #
1113
- # permitted_scalar_filter(params, "zipcode")
1159
+ # permitted_scalar_filter(params, "zipcode")
1114
1160
  #
1115
- # puts params.keys # => ["zipcode"]
1161
+ # puts params.keys # => ["zipcode"]
1116
1162
  def permitted_scalar_filter(params, permitted_key)
1117
1163
  permitted_key = permitted_key.to_s
1118
1164
 
@@ -1207,77 +1253,76 @@ module ActionController
1207
1253
  end
1208
1254
  end
1209
1255
 
1210
- # = Strong \Parameters
1256
+ # # Strong Parameters
1211
1257
  #
1212
- # It provides an interface for protecting attributes from end-user
1213
- # assignment. This makes Action Controller parameters forbidden
1214
- # to be used in Active Model mass assignment until they have been explicitly
1215
- # enumerated.
1258
+ # It provides an interface for protecting attributes from end-user assignment.
1259
+ # This makes Action Controller parameters forbidden to be used in Active Model
1260
+ # mass assignment until they have been explicitly enumerated.
1216
1261
  #
1217
1262
  # In addition, parameters can be marked as required and flow through a
1218
- # predefined raise/rescue flow to end up as a <tt>400 Bad Request</tt> with no
1219
- # effort.
1263
+ # predefined raise/rescue flow to end up as a `400 Bad Request` with no effort.
1220
1264
  #
1221
- # class PeopleController < ActionController::Base
1222
- # # Using "Person.create(params[:person])" would raise an
1223
- # # ActiveModel::ForbiddenAttributesError exception because it'd
1224
- # # be using mass assignment without an explicit permit step.
1225
- # # This is the recommended form:
1226
- # def create
1227
- # Person.create(person_params)
1228
- # end
1229
- #
1230
- # # This will pass with flying colors as long as there's a person key in the
1231
- # # parameters, otherwise it'll raise an ActionController::ParameterMissing
1232
- # # exception, which will get caught by ActionController::Base and turned
1233
- # # into a 400 Bad Request reply.
1234
- # def update
1235
- # redirect_to current_account.people.find(params[:id]).tap { |person|
1236
- # person.update!(person_params)
1237
- # }
1238
- # end
1265
+ # class PeopleController < ActionController::Base
1266
+ # # Using "Person.create(params[:person])" would raise an
1267
+ # # ActiveModel::ForbiddenAttributesError exception because it'd
1268
+ # # be using mass assignment without an explicit permit step.
1269
+ # # This is the recommended form:
1270
+ # def create
1271
+ # Person.create(person_params)
1272
+ # end
1239
1273
  #
1240
- # private
1241
- # # Using a private method to encapsulate the permissible parameters is
1242
- # # a good pattern since you'll be able to reuse the same permit
1243
- # # list between create and update. Also, you can specialize this method
1244
- # # with per-user checking of permissible attributes.
1245
- # def person_params
1246
- # params.require(:person).permit(:name, :age)
1274
+ # # This will pass with flying colors as long as there's a person key in the
1275
+ # # parameters, otherwise it'll raise an ActionController::ParameterMissing
1276
+ # # exception, which will get caught by ActionController::Base and turned
1277
+ # # into a 400 Bad Request reply.
1278
+ # def update
1279
+ # redirect_to current_account.people.find(params[:id]).tap { |person|
1280
+ # person.update!(person_params)
1281
+ # }
1247
1282
  # end
1248
- # end
1249
1283
  #
1250
- # In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you
1251
- # will need to specify which nested attributes should be permitted. You might want
1252
- # to allow +:id+ and +:_destroy+, see ActiveRecord::NestedAttributes for more information.
1284
+ # private
1285
+ # # Using a private method to encapsulate the permissible parameters is
1286
+ # # a good pattern since you'll be able to reuse the same permit
1287
+ # # list between create and update. Also, you can specialize this method
1288
+ # # with per-user checking of permissible attributes.
1289
+ # def person_params
1290
+ # params.require(:person).permit(:name, :age)
1291
+ # end
1292
+ # end
1253
1293
  #
1254
- # class Person
1255
- # has_many :pets
1256
- # accepts_nested_attributes_for :pets
1257
- # end
1294
+ # In order to use `accepts_nested_attributes_for` with Strong Parameters, you
1295
+ # will need to specify which nested attributes should be permitted. You might
1296
+ # want to allow `:id` and `:_destroy`, see ActiveRecord::NestedAttributes for
1297
+ # more information.
1258
1298
  #
1259
- # class PeopleController < ActionController::Base
1260
- # def create
1261
- # Person.create(person_params)
1299
+ # class Person
1300
+ # has_many :pets
1301
+ # accepts_nested_attributes_for :pets
1262
1302
  # end
1263
1303
  #
1264
- # ...
1304
+ # class PeopleController < ActionController::Base
1305
+ # def create
1306
+ # Person.create(person_params)
1307
+ # end
1265
1308
  #
1266
- # private
1309
+ # ...
1267
1310
  #
1268
- # def person_params
1269
- # # It's mandatory to specify the nested attributes that should be permitted.
1270
- # # If you use `permit` with just the key that points to the nested attributes hash,
1271
- # # it will return an empty hash.
1272
- # params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ])
1273
- # end
1274
- # end
1311
+ # private
1312
+ #
1313
+ # def person_params
1314
+ # # It's mandatory to specify the nested attributes that should be permitted.
1315
+ # # If you use `permit` with just the key that points to the nested attributes hash,
1316
+ # # it will return an empty hash.
1317
+ # params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ])
1318
+ # end
1319
+ # end
1275
1320
  #
1276
- # See ActionController::Parameters.require and ActionController::Parameters.permit
1277
- # for more information.
1321
+ # See ActionController::Parameters.require and
1322
+ # ActionController::Parameters.permit for more information.
1278
1323
  module StrongParameters
1279
- # Returns a new ActionController::Parameters object that
1280
- # has been instantiated with the <tt>request.parameters</tt>.
1324
+ # Returns a new ActionController::Parameters object that has been instantiated
1325
+ # with the `request.parameters`.
1281
1326
  def params
1282
1327
  @_params ||= begin
1283
1328
  context = {
@@ -1290,9 +1335,9 @@ module ActionController
1290
1335
  end
1291
1336
  end
1292
1337
 
1293
- # Assigns the given +value+ to the +params+ hash. If +value+
1294
- # is a Hash, this will create an ActionController::Parameters
1295
- # object that has been instantiated with the given +value+ hash.
1338
+ # Assigns the given `value` to the `params` hash. If `value` is a Hash, this
1339
+ # will create an ActionController::Parameters object that has been instantiated
1340
+ # with the given `value` hash.
1296
1341
  def params=(value)
1297
1342
  @_params = value.is_a?(Hash) ? Parameters.new(value) : value
1298
1343
  end