actionpack 6.1.7.5 → 7.1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +355 -435
- data/MIT-LICENSE +2 -1
- data/README.rdoc +6 -7
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +33 -37
- data/lib/abstract_controller/caching/fragments.rb +4 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +50 -11
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +78 -30
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
- data/lib/abstract_controller/rendering.rb +12 -14
- data/lib/abstract_controller/translation.rb +26 -7
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +12 -10
- data/lib/action_controller/base.rb +8 -21
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +4 -2
- data/lib/action_controller/log_subscriber.rb +20 -7
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +137 -102
- data/lib/action_controller/metal/content_security_policy.rb +37 -3
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +25 -31
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +27 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/head.rb +9 -7
- data/lib/action_controller/metal/helpers.rb +5 -16
- data/lib/action_controller/metal/http_authentication.rb +78 -42
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +62 -50
- data/lib/action_controller/metal/live.rb +67 -2
- data/lib/action_controller/metal/mime_responds.rb +5 -5
- data/lib/action_controller/metal/params_wrapper.rb +24 -13
- data/lib/action_controller/metal/permissions_policy.rb +20 -29
- data/lib/action_controller/metal/redirecting.rb +96 -23
- data/lib/action_controller/metal/renderers.rb +14 -15
- data/lib/action_controller/metal/rendering.rb +121 -16
- data/lib/action_controller/metal/request_forgery_protection.rb +208 -68
- data/lib/action_controller/metal/rescue.rb +7 -4
- data/lib/action_controller/metal/streaming.rb +74 -36
- data/lib/action_controller/metal/strong_parameters.rb +254 -151
- data/lib/action_controller/metal/testing.rb +9 -2
- data/lib/action_controller/metal/url_for.rb +10 -5
- data/lib/action_controller/metal.rb +89 -34
- data/lib/action_controller/railtie.rb +66 -9
- data/lib/action_controller/renderer.rb +99 -85
- data/lib/action_controller/test_case.rb +42 -11
- data/lib/action_controller.rb +10 -6
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +21 -16
- data/lib/action_dispatch/http/content_security_policy.rb +122 -44
- data/lib/action_dispatch/http/filter_parameters.rb +14 -23
- data/lib/action_dispatch/http/headers.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -15
- data/lib/action_dispatch/http/mime_type.rb +43 -22
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +6 -6
- data/lib/action_dispatch/http/permissions_policy.rb +57 -19
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +75 -51
- data/lib/action_dispatch/http/response.rb +81 -77
- data/lib/action_dispatch/http/upload.rb +15 -2
- data/lib/action_dispatch/http/url.rb +11 -19
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +36 -27
- data/lib/action_dispatch/journey/route.rb +8 -14
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +10 -9
- data/lib/action_dispatch/journey/routes.rb +5 -5
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -7
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +97 -107
- data/lib/action_dispatch/middleware/debug_exceptions.rb +31 -28
- data/lib/action_dispatch/middleware/debug_locks.rb +7 -4
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +190 -27
- data/lib/action_dispatch/middleware/executor.rb +3 -0
- data/lib/action_dispatch/middleware/flash.rb +24 -18
- data/lib/action_dispatch/middleware/host_authorization.rb +19 -20
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +32 -19
- data/lib/action_dispatch/middleware/request_id.rb +5 -3
- data/lib/action_dispatch/middleware/server_timing.rb +76 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +6 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +19 -13
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +30 -25
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +34 -11
- data/lib/action_dispatch/middleware/static.rb +16 -16
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +5 -5
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +10 -5
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +9 -9
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +45 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -15
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +6 -6
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +64 -55
- data/lib/action_dispatch/railtie.rb +20 -4
- data/lib/action_dispatch/request/session.rb +59 -19
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +55 -7
- data/lib/action_dispatch/routing/mapper.rb +117 -107
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +20 -8
- data/lib/action_dispatch/routing/route_set.rb +67 -27
- data/lib/action_dispatch/routing/routes_proxy.rb +11 -16
- data/lib/action_dispatch/routing/url_for.rb +29 -26
- data/lib/action_dispatch/routing.rb +12 -13
- data/lib/action_dispatch/system_test_case.rb +8 -8
- data/lib/action_dispatch/system_testing/browser.rb +20 -29
- data/lib/action_dispatch/system_testing/driver.rb +34 -18
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +35 -20
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +0 -8
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +14 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +70 -30
- data/lib/action_dispatch/testing/assertions.rb +3 -4
- data/lib/action_dispatch/testing/integration.rb +33 -25
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +5 -30
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +34 -2
- data/lib/action_dispatch.rb +38 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +67 -30
@@ -4,6 +4,7 @@ require "active_support/core_ext/hash/indifferent_access"
|
|
4
4
|
require "active_support/core_ext/array/wrap"
|
5
5
|
require "active_support/core_ext/string/filters"
|
6
6
|
require "active_support/core_ext/object/to_query"
|
7
|
+
require "active_support/deep_mergeable"
|
7
8
|
require "action_dispatch/http/upload"
|
8
9
|
require "rack/test"
|
9
10
|
require "stringio"
|
@@ -27,28 +28,13 @@ module ActionController
|
|
27
28
|
super("param is missing or the value is empty: #{param}")
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
@error = error
|
33
|
-
end
|
34
|
-
|
35
|
-
def corrections
|
36
|
-
if @error.param && @error.keys
|
37
|
-
maybe_these = @error.keys
|
31
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
32
|
+
include DidYouMean::Correctable # :nodoc:
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
}.reverse.first(4)
|
42
|
-
else
|
43
|
-
[]
|
44
|
-
end
|
34
|
+
def corrections # :nodoc:
|
35
|
+
@corrections ||= DidYouMean::SpellChecker.new(dictionary: keys).correct(param.to_s)
|
45
36
|
end
|
46
37
|
end
|
47
|
-
|
48
|
-
# We may not have DYM, and DYM might not let us register error handlers
|
49
|
-
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
50
|
-
DidYouMean.correct_error(self, Correction)
|
51
|
-
end
|
52
38
|
end
|
53
39
|
|
54
40
|
# Raised when a supplied parameter is not expected and
|
@@ -79,7 +65,14 @@ module ActionController
|
|
79
65
|
end
|
80
66
|
end
|
81
67
|
|
82
|
-
#
|
68
|
+
# Raised when initializing Parameters with keys that aren't strings or symbols.
|
69
|
+
#
|
70
|
+
# ActionController::Parameters.new(123 => 456)
|
71
|
+
# # => ActionController::InvalidParameterKey: all keys must be Strings or Symbols, got: Integer
|
72
|
+
class InvalidParameterKey < ArgumentError
|
73
|
+
end
|
74
|
+
|
75
|
+
# = Action Controller \Parameters
|
83
76
|
#
|
84
77
|
# Allows you to choose which attributes should be permitted for mass updating
|
85
78
|
# and thus prevent accidentally exposing that which shouldn't be exposed.
|
@@ -96,7 +89,7 @@ module ActionController
|
|
96
89
|
# })
|
97
90
|
#
|
98
91
|
# permitted = params.require(:person).permit(:name, :age)
|
99
|
-
# permitted # =>
|
92
|
+
# permitted # => #<ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
|
100
93
|
# permitted.permitted? # => true
|
101
94
|
#
|
102
95
|
# Person.first.update!(permitted)
|
@@ -106,11 +99,13 @@ module ActionController
|
|
106
99
|
#
|
107
100
|
# * +permit_all_parameters+ - If it's +true+, all the parameters will be
|
108
101
|
# permitted by default. The default is +false+.
|
109
|
-
# * +action_on_unpermitted_parameters+ -
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
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.
|
114
109
|
#
|
115
110
|
# Examples:
|
116
111
|
#
|
@@ -124,7 +119,7 @@ module ActionController
|
|
124
119
|
#
|
125
120
|
# params = ActionController::Parameters.new(a: "123", b: "456")
|
126
121
|
# params.permit(:c)
|
127
|
-
# # =>
|
122
|
+
# # => #<ActionController::Parameters {} permitted: true>
|
128
123
|
#
|
129
124
|
# ActionController::Parameters.action_on_unpermitted_parameters = :raise
|
130
125
|
#
|
@@ -136,79 +131,82 @@ module ActionController
|
|
136
131
|
# environment they should only be set once at boot-time and never mutated at
|
137
132
|
# runtime.
|
138
133
|
#
|
139
|
-
# You can fetch values of
|
134
|
+
# You can fetch values of +ActionController::Parameters+ using either
|
140
135
|
# <tt>:key</tt> or <tt>"key"</tt>.
|
141
136
|
#
|
142
137
|
# params = ActionController::Parameters.new(key: "value")
|
143
138
|
# params[:key] # => "value"
|
144
139
|
# params["key"] # => "value"
|
145
140
|
class Parameters
|
141
|
+
include ActiveSupport::DeepMergeable
|
142
|
+
|
146
143
|
cattr_accessor :permit_all_parameters, instance_accessor: false, default: false
|
147
144
|
|
148
145
|
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
|
149
146
|
|
150
147
|
##
|
151
|
-
# :method:
|
148
|
+
# :method: deep_merge
|
152
149
|
#
|
153
150
|
# :call-seq:
|
154
|
-
#
|
151
|
+
# deep_merge(other_hash, &block)
|
155
152
|
#
|
156
|
-
# Returns a
|
157
|
-
|
158
|
-
##
|
159
|
-
# :method: each_key
|
153
|
+
# Returns a new +ActionController::Parameters+ instance with +self+ and +other_hash+ merged recursively.
|
160
154
|
#
|
161
|
-
#
|
162
|
-
#
|
155
|
+
# Like with <tt>Hash#merge</tt> in the standard library, a block can be provided
|
156
|
+
# to merge values.
|
163
157
|
#
|
164
|
-
|
165
|
-
#
|
158
|
+
#--
|
159
|
+
# Implemented by ActiveSupport::DeepMergeable#deep_merge.
|
166
160
|
|
167
161
|
##
|
168
|
-
# :method:
|
162
|
+
# :method: deep_merge!
|
169
163
|
#
|
170
164
|
# :call-seq:
|
171
|
-
#
|
165
|
+
# deep_merge!(other_hash, &block)
|
172
166
|
#
|
173
|
-
#
|
167
|
+
# Same as +#deep_merge+, but modifies +self+.
|
168
|
+
#
|
169
|
+
#--
|
170
|
+
# Implemented by ActiveSupport::DeepMergeable#deep_merge!.
|
174
171
|
|
175
172
|
##
|
176
|
-
# :method:
|
173
|
+
# :method: as_json
|
177
174
|
#
|
178
175
|
# :call-seq:
|
179
|
-
#
|
176
|
+
# as_json(options=nil)
|
180
177
|
#
|
181
|
-
# Returns
|
178
|
+
# Returns a hash that can be used as the JSON representation for the parameters.
|
182
179
|
|
183
180
|
##
|
184
|
-
# :method:
|
181
|
+
# :method: each_key
|
185
182
|
#
|
186
183
|
# :call-seq:
|
187
|
-
#
|
184
|
+
# each_key(&block)
|
188
185
|
#
|
189
|
-
#
|
186
|
+
# Calls block once for each key in the parameters, passing the key.
|
187
|
+
# If no block is given, an enumerator is returned instead.
|
190
188
|
|
191
189
|
##
|
192
|
-
# :method:
|
190
|
+
# :method: empty?
|
193
191
|
#
|
194
192
|
# :call-seq:
|
195
|
-
#
|
193
|
+
# empty?()
|
196
194
|
#
|
197
|
-
# Returns true if the
|
195
|
+
# Returns true if the parameters have no key/value pairs.
|
198
196
|
|
199
197
|
##
|
200
|
-
# :method:
|
198
|
+
# :method: exclude?
|
201
199
|
#
|
202
200
|
# :call-seq:
|
203
|
-
#
|
201
|
+
# exclude?(key)
|
204
202
|
#
|
205
|
-
# Returns true if the given key is present in the parameters.
|
203
|
+
# Returns true if the given key is not present in the parameters.
|
206
204
|
|
207
205
|
##
|
208
|
-
# :method:
|
206
|
+
# :method: include?
|
209
207
|
#
|
210
208
|
# :call-seq:
|
211
|
-
#
|
209
|
+
# include?(key)
|
212
210
|
#
|
213
211
|
# Returns true if the given key is present in the parameters.
|
214
212
|
|
@@ -228,40 +226,31 @@ module ActionController
|
|
228
226
|
#
|
229
227
|
# Returns the content of the parameters as a string.
|
230
228
|
|
231
|
-
|
232
|
-
# :method: value?
|
233
|
-
#
|
234
|
-
# :call-seq:
|
235
|
-
# value?(value)
|
236
|
-
#
|
237
|
-
# Returns true if the given value is present for some key in the parameters.
|
238
|
-
|
239
|
-
##
|
240
|
-
# :method: values
|
241
|
-
#
|
242
|
-
# :call-seq:
|
243
|
-
# values()
|
244
|
-
#
|
245
|
-
# Returns a new array of the values of the parameters.
|
246
|
-
delegate :keys, :key?, :has_key?, :member?, :values, :has_value?, :value?, :empty?, :include?,
|
229
|
+
delegate :keys, :empty?, :exclude?, :include?,
|
247
230
|
:as_json, :to_s, :each_key, to: :@parameters
|
248
231
|
|
232
|
+
alias_method :has_key?, :include?
|
233
|
+
alias_method :key?, :include?
|
234
|
+
alias_method :member?, :include?
|
235
|
+
|
249
236
|
# By default, never raise an UnpermittedParameters exception if these
|
250
237
|
# params are present. The default includes both 'controller' and 'action'
|
251
238
|
# because they are added by Rails and should be of no concern. One way
|
252
|
-
# to change these is to specify
|
239
|
+
# to change these is to specify +always_permitted_parameters+ in your
|
253
240
|
# config. For instance:
|
254
241
|
#
|
255
242
|
# config.action_controller.always_permitted_parameters = %w( controller action format )
|
256
243
|
cattr_accessor :always_permitted_parameters, default: %w( controller action )
|
257
244
|
|
245
|
+
cattr_accessor :allow_deprecated_parameters_hash_equality, default: true, instance_accessor: false
|
246
|
+
|
258
247
|
class << self
|
259
248
|
def nested_attribute?(key, value) # :nodoc:
|
260
249
|
/\A-?\d+\z/.match?(key) && (value.is_a?(Hash) || value.is_a?(Parameters))
|
261
250
|
end
|
262
251
|
end
|
263
252
|
|
264
|
-
# Returns a new
|
253
|
+
# Returns a new +ActionController::Parameters+ instance.
|
265
254
|
# Also, sets the +permitted+ attribute to the default value of
|
266
255
|
# <tt>ActionController::Parameters.permit_all_parameters</tt>.
|
267
256
|
#
|
@@ -277,8 +266,15 @@ module ActionController
|
|
277
266
|
# params = ActionController::Parameters.new(name: "Francesco")
|
278
267
|
# params.permitted? # => true
|
279
268
|
# Person.new(params) # => #<Person id: nil, name: "Francesco">
|
280
|
-
def initialize(parameters = {})
|
269
|
+
def initialize(parameters = {}, logging_context = {})
|
270
|
+
parameters.each_key do |key|
|
271
|
+
unless key.is_a?(String) || key.is_a?(Symbol)
|
272
|
+
raise InvalidParameterKey, "all keys must be Strings or Symbols, got: #{key.class}"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
281
276
|
@parameters = parameters.with_indifferent_access
|
277
|
+
@logging_context = logging_context
|
282
278
|
@permitted = self.class.permit_all_parameters
|
283
279
|
end
|
284
280
|
|
@@ -288,16 +284,34 @@ module ActionController
|
|
288
284
|
if other.respond_to?(:permitted?)
|
289
285
|
permitted? == other.permitted? && parameters == other.parameters
|
290
286
|
else
|
291
|
-
|
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
|
292
301
|
end
|
293
302
|
end
|
294
|
-
|
303
|
+
|
304
|
+
def eql?(other)
|
305
|
+
self.class == other.class &&
|
306
|
+
permitted? == other.permitted? &&
|
307
|
+
parameters.eql?(other.parameters)
|
308
|
+
end
|
295
309
|
|
296
310
|
def hash
|
297
|
-
[@parameters
|
311
|
+
[self.class, @parameters, @permitted].hash
|
298
312
|
end
|
299
313
|
|
300
|
-
# Returns a safe
|
314
|
+
# Returns a safe ActiveSupport::HashWithIndifferentAccess
|
301
315
|
# representation of the parameters with all unpermitted keys removed.
|
302
316
|
#
|
303
317
|
# params = ActionController::Parameters.new({
|
@@ -309,9 +323,9 @@ module ActionController
|
|
309
323
|
#
|
310
324
|
# safe_params = params.permit(:name)
|
311
325
|
# safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
|
312
|
-
def to_h
|
326
|
+
def to_h(&block)
|
313
327
|
if permitted?
|
314
|
-
convert_parameters_to_hashes(@parameters, :to_h)
|
328
|
+
convert_parameters_to_hashes(@parameters, :to_h, &block)
|
315
329
|
else
|
316
330
|
raise UnfilteredParameters
|
317
331
|
end
|
@@ -357,18 +371,15 @@ module ActionController
|
|
357
371
|
# safe_params.to_query("user")
|
358
372
|
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
359
373
|
#
|
360
|
-
# The string pairs "key=value" that conform the query string
|
374
|
+
# The string pairs <tt>"key=value"</tt> that conform the query string
|
361
375
|
# are sorted lexicographically in ascending order.
|
362
|
-
#
|
363
|
-
# This method is also aliased as +to_param+.
|
364
376
|
def to_query(*args)
|
365
377
|
to_h.to_query(*args)
|
366
378
|
end
|
367
379
|
alias_method :to_param, :to_query
|
368
380
|
|
369
|
-
# Returns an unsafe, unfiltered
|
370
|
-
#
|
371
|
-
# parameters.
|
381
|
+
# Returns an unsafe, unfiltered ActiveSupport::HashWithIndifferentAccess
|
382
|
+
# representation of the parameters.
|
372
383
|
#
|
373
384
|
# params = ActionController::Parameters.new({
|
374
385
|
# name: "Senjougahara Hitagi",
|
@@ -404,11 +415,16 @@ module ActionController
|
|
404
415
|
self
|
405
416
|
end
|
406
417
|
|
418
|
+
# Returns a new array of the values of the parameters.
|
419
|
+
def values
|
420
|
+
to_enum(:each_value).to_a
|
421
|
+
end
|
422
|
+
|
407
423
|
# Attribute that keeps track of converted arrays, if any, to avoid double
|
408
424
|
# looping in the common use case permit + mass-assignment. Defined in a
|
409
425
|
# method to instantiate it only if needed.
|
410
426
|
#
|
411
|
-
# Testing membership still loops, but it's going to be faster than our own
|
427
|
+
# \Testing membership still loops, but it's going to be faster than our own
|
412
428
|
# loop that converts values. Also, we are not going to build a new array
|
413
429
|
# object per fetch.
|
414
430
|
def converted_arrays
|
@@ -454,9 +470,9 @@ module ActionController
|
|
454
470
|
# either present or the singleton +false+, returns said value:
|
455
471
|
#
|
456
472
|
# ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
|
457
|
-
# # =>
|
473
|
+
# # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
|
458
474
|
#
|
459
|
-
# Otherwise raises
|
475
|
+
# Otherwise raises ActionController::ParameterMissing:
|
460
476
|
#
|
461
477
|
# ActionController::Parameters.new.require(:person)
|
462
478
|
# # ActionController::ParameterMissing: param is missing or the value is empty: person
|
@@ -508,10 +524,9 @@ module ActionController
|
|
508
524
|
end
|
509
525
|
end
|
510
526
|
|
511
|
-
# Alias of #require.
|
512
527
|
alias :required :require
|
513
528
|
|
514
|
-
# Returns a new
|
529
|
+
# Returns a new +ActionController::Parameters+ instance that
|
515
530
|
# includes only the given +filters+ and sets the +permitted+ attribute
|
516
531
|
# for the object to +true+. This is useful for limiting which attributes
|
517
532
|
# should be allowed for mass updating.
|
@@ -530,7 +545,7 @@ module ActionController
|
|
530
545
|
# +:name+ passes if it is a key of +params+ whose associated value is of type
|
531
546
|
# +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+,
|
532
547
|
# +Date+, +Time+, +DateTime+, +StringIO+, +IO+,
|
533
|
-
#
|
548
|
+
# ActionDispatch::Http::UploadedFile or +Rack::Test::UploadedFile+.
|
534
549
|
# Otherwise, the key +:name+ is filtered out.
|
535
550
|
#
|
536
551
|
# You may declare that the parameter should be an array of permitted scalars
|
@@ -582,13 +597,48 @@ module ActionController
|
|
582
597
|
# })
|
583
598
|
#
|
584
599
|
# params.require(:person).permit(:contact)
|
585
|
-
# # =>
|
600
|
+
# # => #<ActionController::Parameters {} permitted: true>
|
586
601
|
#
|
587
602
|
# params.require(:person).permit(contact: :phone)
|
588
|
-
# # =>
|
603
|
+
# # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
|
589
604
|
#
|
590
605
|
# params.require(:person).permit(contact: [ :email, :phone ])
|
591
|
-
# # =>
|
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"}}}
|
592
642
|
def permit(*filters)
|
593
643
|
params = self.class.new
|
594
644
|
|
@@ -610,29 +660,29 @@ module ActionController
|
|
610
660
|
# returns +nil+.
|
611
661
|
#
|
612
662
|
# params = ActionController::Parameters.new(person: { name: "Francesco" })
|
613
|
-
# params[:person] # =>
|
663
|
+
# params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
|
614
664
|
# params[:none] # => nil
|
615
665
|
def [](key)
|
616
666
|
convert_hashes_to_parameters(key, @parameters[key])
|
617
667
|
end
|
618
668
|
|
619
669
|
# Assigns a value to a given +key+. The given key may still get filtered out
|
620
|
-
# when
|
670
|
+
# when #permit is called.
|
621
671
|
def []=(key, value)
|
622
672
|
@parameters[key] = value
|
623
673
|
end
|
624
674
|
|
625
675
|
# Returns a parameter for the given +key+. If the +key+
|
626
676
|
# can't be found, there are several options: With no other arguments,
|
627
|
-
# it will raise an
|
677
|
+
# it will raise an ActionController::ParameterMissing error;
|
628
678
|
# if a second argument is given, then that is returned (converted to an
|
629
|
-
# instance of ActionController::Parameters if possible); if a block
|
679
|
+
# instance of +ActionController::Parameters+ if possible); if a block
|
630
680
|
# is given, then that will be run and its result returned.
|
631
681
|
#
|
632
682
|
# params = ActionController::Parameters.new(person: { name: "Francesco" })
|
633
|
-
# params.fetch(:person) # =>
|
683
|
+
# params.fetch(:person) # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
|
634
684
|
# params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none
|
635
|
-
# params.fetch(:none, {}) # =>
|
685
|
+
# params.fetch(:none, {}) # => #<ActionController::Parameters {} permitted: false>
|
636
686
|
# params.fetch(:none, "Francesco") # => "Francesco"
|
637
687
|
# params.fetch(:none) { "Francesco" } # => "Francesco"
|
638
688
|
def fetch(key, *args)
|
@@ -661,49 +711,50 @@ module ActionController
|
|
661
711
|
@parameters.dig(*keys)
|
662
712
|
end
|
663
713
|
|
664
|
-
# Returns a new
|
714
|
+
# Returns a new +ActionController::Parameters+ instance that
|
665
715
|
# includes only the given +keys+. If the given +keys+
|
666
716
|
# don't exist, returns an empty hash.
|
667
717
|
#
|
668
718
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
669
|
-
# params.slice(:a, :b) # =>
|
670
|
-
# params.slice(:d) # =>
|
719
|
+
# params.slice(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
|
720
|
+
# params.slice(:d) # => #<ActionController::Parameters {} permitted: false>
|
671
721
|
def slice(*keys)
|
672
722
|
new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
|
673
723
|
end
|
674
724
|
|
675
|
-
# Returns current
|
725
|
+
# Returns the current +ActionController::Parameters+ instance which
|
676
726
|
# contains only the given +keys+.
|
677
727
|
def slice!(*keys)
|
678
728
|
@parameters.slice!(*keys)
|
679
729
|
self
|
680
730
|
end
|
681
731
|
|
682
|
-
# Returns a new
|
732
|
+
# Returns a new +ActionController::Parameters+ instance that
|
683
733
|
# filters out the given +keys+.
|
684
734
|
#
|
685
735
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
686
|
-
# params.except(:a, :b) # =>
|
687
|
-
# params.except(:d) # =>
|
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>
|
688
738
|
def except(*keys)
|
689
739
|
new_instance_with_inherited_permitted_status(@parameters.except(*keys))
|
690
740
|
end
|
741
|
+
alias_method :without, :except
|
691
742
|
|
692
743
|
# Removes and returns the key/value pairs matching the given keys.
|
693
744
|
#
|
694
745
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
695
|
-
# params.extract!(:a, :b) # =>
|
696
|
-
# params # =>
|
746
|
+
# params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
|
747
|
+
# params # => #<ActionController::Parameters {"c"=>3} permitted: false>
|
697
748
|
def extract!(*keys)
|
698
749
|
new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
|
699
750
|
end
|
700
751
|
|
701
|
-
# Returns a new
|
752
|
+
# Returns a new +ActionController::Parameters+ instance with the results of
|
702
753
|
# running +block+ once for every value. The keys are unchanged.
|
703
754
|
#
|
704
755
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
705
756
|
# params.transform_values { |x| x * 2 }
|
706
|
-
# # =>
|
757
|
+
# # => #<ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
|
707
758
|
def transform_values
|
708
759
|
return to_enum(:transform_values) unless block_given?
|
709
760
|
new_instance_with_inherited_permitted_status(
|
@@ -712,14 +763,14 @@ module ActionController
|
|
712
763
|
end
|
713
764
|
|
714
765
|
# Performs values transformation and returns the altered
|
715
|
-
#
|
766
|
+
# +ActionController::Parameters+ instance.
|
716
767
|
def transform_values!
|
717
768
|
return to_enum(:transform_values!) unless block_given?
|
718
769
|
@parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
|
719
770
|
self
|
720
771
|
end
|
721
772
|
|
722
|
-
# Returns a new
|
773
|
+
# Returns a new +ActionController::Parameters+ instance with the
|
723
774
|
# results of running +block+ once for every key. The values are unchanged.
|
724
775
|
def transform_keys(&block)
|
725
776
|
return to_enum(:transform_keys) unless block_given?
|
@@ -729,14 +780,14 @@ module ActionController
|
|
729
780
|
end
|
730
781
|
|
731
782
|
# Performs keys transformation and returns the altered
|
732
|
-
#
|
783
|
+
# +ActionController::Parameters+ instance.
|
733
784
|
def transform_keys!(&block)
|
734
785
|
return to_enum(:transform_keys!) unless block_given?
|
735
786
|
@parameters.transform_keys!(&block)
|
736
787
|
self
|
737
788
|
end
|
738
789
|
|
739
|
-
# Returns a new
|
790
|
+
# Returns a new +ActionController::Parameters+ instance with the
|
740
791
|
# results of running +block+ once for every key. This includes the keys
|
741
792
|
# from the root hash and from all nested hashes and arrays. The values are unchanged.
|
742
793
|
def deep_transform_keys(&block)
|
@@ -745,9 +796,9 @@ module ActionController
|
|
745
796
|
)
|
746
797
|
end
|
747
798
|
|
748
|
-
# Returns the
|
749
|
-
# This includes the keys from the root hash and from all
|
750
|
-
# The values are unchanged.
|
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.
|
751
802
|
def deep_transform_keys!(&block)
|
752
803
|
@parameters.deep_transform_keys!(&block)
|
753
804
|
self
|
@@ -755,13 +806,13 @@ module ActionController
|
|
755
806
|
|
756
807
|
# Deletes a key-value pair from +Parameters+ and returns the value. If
|
757
808
|
# +key+ is not found, returns +nil+ (or, with optional code block, yields
|
758
|
-
# +key+ and returns the result).
|
759
|
-
# corresponding +ActionController::Parameters+ object.
|
809
|
+
# +key+ and returns the result). This method is similar to #extract!, which
|
810
|
+
# returns the corresponding +ActionController::Parameters+ object.
|
760
811
|
def delete(key, &block)
|
761
812
|
convert_value_to_parameters(@parameters.delete(key, &block))
|
762
813
|
end
|
763
814
|
|
764
|
-
# Returns a new
|
815
|
+
# Returns a new +ActionController::Parameters+ instance with only
|
765
816
|
# items that the block evaluates to true.
|
766
817
|
def select(&block)
|
767
818
|
new_instance_with_inherited_permitted_status(@parameters.select(&block))
|
@@ -774,7 +825,7 @@ module ActionController
|
|
774
825
|
end
|
775
826
|
alias_method :keep_if, :select!
|
776
827
|
|
777
|
-
# Returns a new
|
828
|
+
# Returns a new +ActionController::Parameters+ instance with items
|
778
829
|
# that the block evaluates to true removed.
|
779
830
|
def reject(&block)
|
780
831
|
new_instance_with_inherited_permitted_status(@parameters.reject(&block))
|
@@ -787,7 +838,7 @@ module ActionController
|
|
787
838
|
end
|
788
839
|
alias_method :delete_if, :reject!
|
789
840
|
|
790
|
-
# Returns a new
|
841
|
+
# Returns a new +ActionController::Parameters+ instance with +nil+ values removed.
|
791
842
|
def compact
|
792
843
|
new_instance_with_inherited_permitted_status(@parameters.compact)
|
793
844
|
end
|
@@ -797,7 +848,7 @@ module ActionController
|
|
797
848
|
self if @parameters.compact!
|
798
849
|
end
|
799
850
|
|
800
|
-
# Returns a new
|
851
|
+
# Returns a new +ActionController::Parameters+ instance without the blank values.
|
801
852
|
# Uses Object#blank? for determining if a value is blank.
|
802
853
|
def compact_blank
|
803
854
|
reject { |_k, v| v.blank? }
|
@@ -809,13 +860,20 @@ module ActionController
|
|
809
860
|
reject! { |_k, v| v.blank? }
|
810
861
|
end
|
811
862
|
|
863
|
+
# Returns true if the given value is present for some key in the parameters.
|
864
|
+
def has_value?(value)
|
865
|
+
each_value.include?(convert_value_to_parameters(value))
|
866
|
+
end
|
867
|
+
|
868
|
+
alias value? has_value?
|
869
|
+
|
812
870
|
# Returns values that were assigned to the given +keys+. Note that all the
|
813
|
-
# +Hash+ objects will be converted to
|
871
|
+
# +Hash+ objects will be converted to +ActionController::Parameters+.
|
814
872
|
def values_at(*keys)
|
815
873
|
convert_value_to_parameters(@parameters.values_at(*keys))
|
816
874
|
end
|
817
875
|
|
818
|
-
# Returns a new
|
876
|
+
# Returns a new +ActionController::Parameters+ instance with all keys from
|
819
877
|
# +other_hash+ merged into current hash.
|
820
878
|
def merge(other_hash)
|
821
879
|
new_instance_with_inherited_permitted_status(
|
@@ -823,15 +881,22 @@ module ActionController
|
|
823
881
|
)
|
824
882
|
end
|
825
883
|
|
826
|
-
|
884
|
+
##
|
885
|
+
# :call-seq: merge!(other_hash)
|
886
|
+
#
|
887
|
+
# Returns the current +ActionController::Parameters+ instance with
|
827
888
|
# +other_hash+ merged into current hash.
|
828
|
-
def merge!(other_hash)
|
829
|
-
@parameters.merge!(other_hash.to_h)
|
889
|
+
def merge!(other_hash, &block)
|
890
|
+
@parameters.merge!(other_hash.to_h, &block)
|
830
891
|
self
|
831
892
|
end
|
832
893
|
|
833
|
-
|
834
|
-
|
894
|
+
def deep_merge?(other_hash) # :nodoc:
|
895
|
+
other_hash.is_a?(ActiveSupport::DeepMergeable)
|
896
|
+
end
|
897
|
+
|
898
|
+
# Returns a new +ActionController::Parameters+ instance with all keys
|
899
|
+
# from current hash merged into +other_hash+.
|
835
900
|
def reverse_merge(other_hash)
|
836
901
|
new_instance_with_inherited_permitted_status(
|
837
902
|
other_hash.to_h.merge(@parameters)
|
@@ -839,7 +904,7 @@ module ActionController
|
|
839
904
|
end
|
840
905
|
alias_method :with_defaults, :reverse_merge
|
841
906
|
|
842
|
-
# Returns current
|
907
|
+
# Returns the current +ActionController::Parameters+ instance with
|
843
908
|
# current hash merged into +other_hash+.
|
844
909
|
def reverse_merge!(other_hash)
|
845
910
|
@parameters.merge!(other_hash.to_h) { |key, left, right| left }
|
@@ -885,13 +950,33 @@ module ActionController
|
|
885
950
|
end
|
886
951
|
end
|
887
952
|
|
888
|
-
|
953
|
+
def encode_with(coder) # :nodoc:
|
954
|
+
coder.map = { "parameters" => @parameters, "permitted" => @permitted }
|
955
|
+
end
|
956
|
+
|
957
|
+
# Returns a duplicate +ActionController::Parameters+ instance with the same permitted parameters.
|
889
958
|
def deep_dup
|
890
|
-
self.class.new(@parameters.deep_dup).tap do |duplicate|
|
959
|
+
self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
|
891
960
|
duplicate.permitted = @permitted
|
892
961
|
end
|
893
962
|
end
|
894
963
|
|
964
|
+
# Returns parameter value for the given +key+ separated by +delimiter+.
|
965
|
+
#
|
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
|
970
|
+
#
|
971
|
+
# Note that if the given +key+'s value contains blank elements, then
|
972
|
+
# the returned array will include empty strings.
|
973
|
+
#
|
974
|
+
# params = ActionController::Parameters.new(tags: "ruby,rails,,web")
|
975
|
+
# params.extract_value(:tags) # => ["ruby", "rails", "", "web"]
|
976
|
+
def extract_value(key, delimiter: "_")
|
977
|
+
@parameters[key]&.split(delimiter, -1)
|
978
|
+
end
|
979
|
+
|
895
980
|
protected
|
896
981
|
attr_reader :parameters
|
897
982
|
|
@@ -909,19 +994,20 @@ module ActionController
|
|
909
994
|
|
910
995
|
private
|
911
996
|
def new_instance_with_inherited_permitted_status(hash)
|
912
|
-
self.class.new(hash).tap do |new_instance|
|
997
|
+
self.class.new(hash, @logging_context).tap do |new_instance|
|
913
998
|
new_instance.permitted = @permitted
|
914
999
|
end
|
915
1000
|
end
|
916
1001
|
|
917
|
-
def convert_parameters_to_hashes(value, using)
|
1002
|
+
def convert_parameters_to_hashes(value, using, &block)
|
918
1003
|
case value
|
919
1004
|
when Array
|
920
1005
|
value.map { |v| convert_parameters_to_hashes(v, using) }
|
921
1006
|
when Hash
|
922
|
-
value.transform_values do |v|
|
1007
|
+
transformed = value.transform_values do |v|
|
923
1008
|
convert_parameters_to_hashes(v, using)
|
924
|
-
end
|
1009
|
+
end
|
1010
|
+
(block_given? ? transformed.to_h(&block) : transformed).with_indifferent_access
|
925
1011
|
when Parameters
|
926
1012
|
value.send(using)
|
927
1013
|
else
|
@@ -943,18 +1029,24 @@ module ActionController
|
|
943
1029
|
converted_arrays << converted.dup
|
944
1030
|
converted
|
945
1031
|
when Hash
|
946
|
-
self.class.new(value)
|
1032
|
+
self.class.new(value, @logging_context)
|
947
1033
|
else
|
948
1034
|
value
|
949
1035
|
end
|
950
1036
|
end
|
951
1037
|
|
952
|
-
def
|
1038
|
+
def specify_numeric_keys?(filter)
|
1039
|
+
if filter.respond_to?(:keys)
|
1040
|
+
filter.keys.any? { |key| /\A-?\d+\z/.match?(key) }
|
1041
|
+
end
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
def each_element(object, filter, &block)
|
953
1045
|
case object
|
954
1046
|
when Array
|
955
|
-
object.grep(Parameters).
|
1047
|
+
object.grep(Parameters).filter_map(&block)
|
956
1048
|
when Parameters
|
957
|
-
if object.nested_attributes?
|
1049
|
+
if object.nested_attributes? && !specify_numeric_keys?(filter)
|
958
1050
|
object.each_nested_attribute(&block)
|
959
1051
|
else
|
960
1052
|
yield object
|
@@ -968,7 +1060,7 @@ module ActionController
|
|
968
1060
|
case self.class.action_on_unpermitted_parameters
|
969
1061
|
when :log
|
970
1062
|
name = "unpermitted_parameters.action_controller"
|
971
|
-
ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys)
|
1063
|
+
ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys, context: @logging_context)
|
972
1064
|
when :raise
|
973
1065
|
raise ActionController::UnpermittedParameters.new(unpermitted_keys)
|
974
1066
|
end
|
@@ -986,10 +1078,11 @@ module ActionController
|
|
986
1078
|
# This is a list of permitted scalar types that includes the ones
|
987
1079
|
# supported in XML and JSON requests.
|
988
1080
|
#
|
989
|
-
# This list is in particular used to filter ordinary requests, String goes
|
1081
|
+
# This list is in particular used to filter ordinary requests, \String goes
|
990
1082
|
# as first element to quickly short-circuit the common case.
|
991
1083
|
#
|
992
|
-
# If you modify this collection please update the
|
1084
|
+
# If you modify this collection please update the one in the #permit doc
|
1085
|
+
# as well.
|
993
1086
|
PERMITTED_SCALAR_TYPES = [
|
994
1087
|
String,
|
995
1088
|
Symbol,
|
@@ -1045,8 +1138,8 @@ module ActionController
|
|
1045
1138
|
value.is_a?(Array) || value.is_a?(Parameters)
|
1046
1139
|
end
|
1047
1140
|
|
1048
|
-
EMPTY_ARRAY = []
|
1049
|
-
EMPTY_HASH = {}
|
1141
|
+
EMPTY_ARRAY = [] # :nodoc:
|
1142
|
+
EMPTY_HASH = {} # :nodoc:
|
1050
1143
|
def hash_filter(params, filter)
|
1051
1144
|
filter = filter.with_indifferent_access
|
1052
1145
|
|
@@ -1067,7 +1160,7 @@ module ActionController
|
|
1067
1160
|
end
|
1068
1161
|
elsif non_scalar?(value)
|
1069
1162
|
# Declaration { user: :name } or { user: [:name, :age, { address: ... }] }.
|
1070
|
-
params[key] = each_element(value) do |element|
|
1163
|
+
params[key] = each_element(value, filter[key]) do |element|
|
1071
1164
|
element.permit(*Array.wrap(filter[key]))
|
1072
1165
|
end
|
1073
1166
|
end
|
@@ -1097,6 +1190,8 @@ module ActionController
|
|
1097
1190
|
case element
|
1098
1191
|
when ->(e) { permitted_scalar?(e) }
|
1099
1192
|
sanitized << element
|
1193
|
+
when Array
|
1194
|
+
sanitized << permit_any_in_array(element)
|
1100
1195
|
when Parameters
|
1101
1196
|
sanitized << permit_any_in_parameters(element)
|
1102
1197
|
else
|
@@ -1112,7 +1207,7 @@ module ActionController
|
|
1112
1207
|
end
|
1113
1208
|
end
|
1114
1209
|
|
1115
|
-
#
|
1210
|
+
# = Strong \Parameters
|
1116
1211
|
#
|
1117
1212
|
# It provides an interface for protecting attributes from end-user
|
1118
1213
|
# assignment. This makes Action Controller parameters forbidden
|
@@ -1184,7 +1279,15 @@ module ActionController
|
|
1184
1279
|
# Returns a new ActionController::Parameters object that
|
1185
1280
|
# has been instantiated with the <tt>request.parameters</tt>.
|
1186
1281
|
def params
|
1187
|
-
@_params ||=
|
1282
|
+
@_params ||= begin
|
1283
|
+
context = {
|
1284
|
+
controller: self.class.name,
|
1285
|
+
action: action_name,
|
1286
|
+
request: request,
|
1287
|
+
params: request.filtered_parameters
|
1288
|
+
}
|
1289
|
+
Parameters.new(request.parameters, context)
|
1290
|
+
end
|
1188
1291
|
end
|
1189
1292
|
|
1190
1293
|
# Assigns the given +value+ to the +params+ hash. If +value+
|