actionpack 7.1.3.4 → 7.2.0.beta1

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

Potentially problematic release.


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

Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -541
  3. data/lib/abstract_controller/asset_paths.rb +2 -0
  4. data/lib/abstract_controller/base.rb +102 -98
  5. data/lib/abstract_controller/caching/fragments.rb +50 -53
  6. data/lib/abstract_controller/caching.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +66 -64
  8. data/lib/abstract_controller/collector.rb +6 -6
  9. data/lib/abstract_controller/deprecator.rb +2 -0
  10. data/lib/abstract_controller/error.rb +2 -0
  11. data/lib/abstract_controller/helpers.rb +70 -85
  12. data/lib/abstract_controller/logger.rb +2 -0
  13. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  14. data/lib/abstract_controller/rendering.rb +13 -12
  15. data/lib/abstract_controller/translation.rb +11 -10
  16. data/lib/abstract_controller/url_for.rb +8 -6
  17. data/lib/abstract_controller.rb +2 -0
  18. data/lib/action_controller/api/api_rendering.rb +2 -0
  19. data/lib/action_controller/api.rb +74 -72
  20. data/lib/action_controller/base.rb +155 -117
  21. data/lib/action_controller/caching.rb +15 -12
  22. data/lib/action_controller/deprecator.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +20 -17
  24. data/lib/action_controller/log_subscriber.rb +3 -1
  25. data/lib/action_controller/metal/allow_browser.rb +119 -0
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +188 -174
  28. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  29. data/lib/action_controller/metal/cookies.rb +4 -2
  30. data/lib/action_controller/metal/data_streaming.rb +64 -55
  31. data/lib/action_controller/metal/default_headers.rb +5 -3
  32. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  34. data/lib/action_controller/metal/exceptions.rb +11 -9
  35. data/lib/action_controller/metal/flash.rb +12 -10
  36. data/lib/action_controller/metal/head.rb +12 -10
  37. data/lib/action_controller/metal/helpers.rb +63 -55
  38. data/lib/action_controller/metal/http_authentication.rb +209 -201
  39. data/lib/action_controller/metal/implicit_render.rb +17 -15
  40. data/lib/action_controller/metal/instrumentation.rb +15 -12
  41. data/lib/action_controller/metal/live.rb +113 -107
  42. data/lib/action_controller/metal/logging.rb +6 -4
  43. data/lib/action_controller/metal/mime_responds.rb +151 -142
  44. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  45. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  46. data/lib/action_controller/metal/permissions_policy.rb +13 -12
  47. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  48. data/lib/action_controller/metal/redirecting.rb +108 -82
  49. data/lib/action_controller/metal/renderers.rb +50 -49
  50. data/lib/action_controller/metal/rendering.rb +103 -75
  51. data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
  52. data/lib/action_controller/metal/rescue.rb +11 -9
  53. data/lib/action_controller/metal/streaming.rb +138 -136
  54. data/lib/action_controller/metal/strong_parameters.rb +525 -480
  55. data/lib/action_controller/metal/testing.rb +2 -0
  56. data/lib/action_controller/metal/url_for.rb +17 -15
  57. data/lib/action_controller/metal.rb +58 -57
  58. data/lib/action_controller/railtie.rb +3 -0
  59. data/lib/action_controller/railties/helpers.rb +2 -0
  60. data/lib/action_controller/renderer.rb +42 -36
  61. data/lib/action_controller/template_assertions.rb +4 -2
  62. data/lib/action_controller/test_case.rb +146 -126
  63. data/lib/action_controller.rb +10 -3
  64. data/lib/action_dispatch/constants.rb +2 -0
  65. data/lib/action_dispatch/deprecator.rb +2 -0
  66. data/lib/action_dispatch/http/cache.rb +27 -26
  67. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  68. data/lib/action_dispatch/http/content_security_policy.rb +44 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +9 -5
  70. data/lib/action_dispatch/http/filter_redirect.rb +15 -1
  71. data/lib/action_dispatch/http/headers.rb +22 -22
  72. data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
  73. data/lib/action_dispatch/http/mime_type.rb +29 -22
  74. data/lib/action_dispatch/http/mime_types.rb +2 -0
  75. data/lib/action_dispatch/http/parameters.rb +11 -9
  76. data/lib/action_dispatch/http/permissions_policy.rb +27 -37
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +71 -71
  79. data/lib/action_dispatch/http/response.rb +61 -61
  80. data/lib/action_dispatch/http/upload.rb +18 -16
  81. data/lib/action_dispatch/http/url.rb +75 -73
  82. data/lib/action_dispatch/journey/formatter.rb +13 -6
  83. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  84. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  85. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  86. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  88. data/lib/action_dispatch/journey/parser.rb +4 -3
  89. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  90. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  91. data/lib/action_dispatch/journey/route.rb +9 -7
  92. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  93. data/lib/action_dispatch/journey/router.rb +4 -2
  94. data/lib/action_dispatch/journey/routes.rb +4 -2
  95. data/lib/action_dispatch/journey/scanner.rb +4 -2
  96. data/lib/action_dispatch/journey/visitors.rb +2 -0
  97. data/lib/action_dispatch/journey.rb +2 -0
  98. data/lib/action_dispatch/log_subscriber.rb +2 -0
  99. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  100. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  101. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  102. data/lib/action_dispatch/middleware/cookies.rb +119 -104
  103. data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
  104. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  105. data/lib/action_dispatch/middleware/debug_view.rb +2 -0
  106. data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
  107. data/lib/action_dispatch/middleware/executor.rb +8 -0
  108. data/lib/action_dispatch/middleware/flash.rb +63 -51
  109. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  110. data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
  111. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  112. data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
  113. data/lib/action_dispatch/middleware/request_id.rb +14 -9
  114. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
  120. data/lib/action_dispatch/middleware/ssl.rb +43 -40
  121. data/lib/action_dispatch/middleware/stack.rb +11 -10
  122. data/lib/action_dispatch/middleware/static.rb +33 -31
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
  124. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
  125. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  126. data/lib/action_dispatch/railtie.rb +2 -4
  127. data/lib/action_dispatch/request/session.rb +23 -21
  128. data/lib/action_dispatch/request/utils.rb +2 -0
  129. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  130. data/lib/action_dispatch/routing/inspector.rb +5 -3
  131. data/lib/action_dispatch/routing/mapper.rb +670 -635
  132. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  133. data/lib/action_dispatch/routing/redirection.rb +37 -32
  134. data/lib/action_dispatch/routing/route_set.rb +59 -45
  135. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  136. data/lib/action_dispatch/routing/url_for.rb +130 -125
  137. data/lib/action_dispatch/routing.rb +150 -148
  138. data/lib/action_dispatch/system_test_case.rb +91 -81
  139. data/lib/action_dispatch/system_testing/browser.rb +10 -3
  140. data/lib/action_dispatch/system_testing/driver.rb +3 -1
  141. data/lib/action_dispatch/system_testing/server.rb +2 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  143. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  144. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  145. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  146. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  147. data/lib/action_dispatch/testing/assertions.rb +2 -0
  148. data/lib/action_dispatch/testing/integration.rb +223 -222
  149. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  150. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  151. data/lib/action_dispatch/testing/test_process.rb +12 -8
  152. data/lib/action_dispatch/testing/test_request.rb +3 -1
  153. data/lib/action_dispatch/testing/test_response.rb +27 -26
  154. data/lib/action_dispatch.rb +22 -28
  155. data/lib/action_pack/gem_version.rb +6 -4
  156. data/lib/action_pack/version.rb +3 -1
  157. data/lib/action_pack.rb +17 -16
  158. metadata +30 -13
@@ -1,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 7.3.
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 7.3.
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