actionpack 7.0.8.4 → 7.1.3.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +358 -362
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/base.rb +20 -11
- data/lib/abstract_controller/caching/fragments.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +31 -6
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/helpers.rb +61 -18
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
- data/lib/abstract_controller/rendering.rb +3 -3
- data/lib/abstract_controller/translation.rb +1 -20
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +5 -3
- data/lib/action_controller/base.rb +3 -17
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +16 -4
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +2 -0
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +2 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +8 -0
- data/lib/action_controller/metal/head.rb +8 -6
- data/lib/action_controller/metal/helpers.rb +3 -14
- data/lib/action_controller/metal/http_authentication.rb +17 -8
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +8 -1
- data/lib/action_controller/metal/live.rb +24 -0
- data/lib/action_controller/metal/mime_responds.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +4 -2
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +7 -7
- data/lib/action_controller/metal/renderers.rb +2 -2
- data/lib/action_controller/metal/rendering.rb +0 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +139 -50
- data/lib/action_controller/metal/rescue.rb +2 -0
- data/lib/action_controller/metal/streaming.rb +70 -30
- data/lib/action_controller/metal/strong_parameters.rb +132 -52
- data/lib/action_controller/metal/url_for.rb +7 -0
- data/lib/action_controller/metal.rb +79 -21
- data/lib/action_controller/railtie.rb +22 -9
- data/lib/action_controller/renderer.rb +98 -65
- data/lib/action_controller/test_case.rb +15 -5
- data/lib/action_controller.rb +8 -1
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +1 -3
- data/lib/action_dispatch/http/content_security_policy.rb +9 -8
- data/lib/action_dispatch/http/filter_parameters.rb +11 -5
- data/lib/action_dispatch/http/headers.rb +2 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
- data/lib/action_dispatch/http/mime_type.rb +35 -12
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +38 -16
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +48 -14
- data/lib/action_dispatch/http/response.rb +80 -59
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +14 -14
- data/lib/action_dispatch/journey/route.rb +3 -2
- data/lib/action_dispatch/journey/router.rb +9 -8
- data/lib/action_dispatch/journey/routes.rb +2 -2
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
- 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 +81 -98
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
- data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +7 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +6 -3
- 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 +17 -16
- data/lib/action_dispatch/middleware/request_id.rb +2 -0
- data/lib/action_dispatch/middleware/server_timing.rb +4 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +19 -15
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +7 -2
- data/lib/action_dispatch/middleware/static.rb +12 -8
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- 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 +46 -37
- data/lib/action_dispatch/railtie.rb +14 -4
- data/lib/action_dispatch/request/session.rb +16 -6
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +54 -6
- data/lib/action_dispatch/routing/mapper.rb +35 -24
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +15 -6
- data/lib/action_dispatch/routing/route_set.rb +52 -22
- data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
- data/lib/action_dispatch/routing/url_for.rb +5 -1
- data/lib/action_dispatch/routing.rb +7 -7
- data/lib/action_dispatch/system_test_case.rb +3 -3
- data/lib/action_dispatch/system_testing/browser.rb +20 -19
- data/lib/action_dispatch/system_testing/driver.rb +13 -21
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +13 -6
- data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
- data/lib/action_dispatch/testing/assertions.rb +3 -1
- data/lib/action_dispatch/testing/integration.rb +27 -17
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +4 -3
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -9
- data/lib/action_dispatch.rb +37 -4
- data/lib/action_pack/gem_version.rb +3 -3
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +62 -26
@@ -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"
|
@@ -64,7 +65,14 @@ module ActionController
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
67
|
-
#
|
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
|
68
76
|
#
|
69
77
|
# Allows you to choose which attributes should be permitted for mass updating
|
70
78
|
# and thus prevent accidentally exposing that which shouldn't be exposed.
|
@@ -92,8 +100,8 @@ module ActionController
|
|
92
100
|
# * +permit_all_parameters+ - If it's +true+, all the parameters will be
|
93
101
|
# permitted by default. The default is +false+.
|
94
102
|
# * +action_on_unpermitted_parameters+ - Controls behavior when parameters that are not explicitly
|
95
|
-
#
|
96
|
-
#
|
103
|
+
# permitted are found. The default value is <tt>:log</tt> in test and development environments,
|
104
|
+
# +false+ otherwise. The values can be:
|
97
105
|
# * +false+ to take no action.
|
98
106
|
# * <tt>:log</tt> to emit an <tt>ActiveSupport::Notifications.instrument</tt> event on the
|
99
107
|
# <tt>unpermitted_parameters.action_controller</tt> topic and log at the DEBUG level.
|
@@ -123,17 +131,44 @@ module ActionController
|
|
123
131
|
# environment they should only be set once at boot-time and never mutated at
|
124
132
|
# runtime.
|
125
133
|
#
|
126
|
-
# You can fetch values of
|
134
|
+
# You can fetch values of +ActionController::Parameters+ using either
|
127
135
|
# <tt>:key</tt> or <tt>"key"</tt>.
|
128
136
|
#
|
129
137
|
# params = ActionController::Parameters.new(key: "value")
|
130
138
|
# params[:key] # => "value"
|
131
139
|
# params["key"] # => "value"
|
132
140
|
class Parameters
|
141
|
+
include ActiveSupport::DeepMergeable
|
142
|
+
|
133
143
|
cattr_accessor :permit_all_parameters, instance_accessor: false, default: false
|
134
144
|
|
135
145
|
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
|
136
146
|
|
147
|
+
##
|
148
|
+
# :method: deep_merge
|
149
|
+
#
|
150
|
+
# :call-seq:
|
151
|
+
# deep_merge(other_hash, &block)
|
152
|
+
#
|
153
|
+
# Returns a new +ActionController::Parameters+ instance with +self+ and +other_hash+ merged recursively.
|
154
|
+
#
|
155
|
+
# Like with <tt>Hash#merge</tt> in the standard library, a block can be provided
|
156
|
+
# to merge values.
|
157
|
+
#
|
158
|
+
#--
|
159
|
+
# Implemented by ActiveSupport::DeepMergeable#deep_merge.
|
160
|
+
|
161
|
+
##
|
162
|
+
# :method: deep_merge!
|
163
|
+
#
|
164
|
+
# :call-seq:
|
165
|
+
# deep_merge!(other_hash, &block)
|
166
|
+
#
|
167
|
+
# Same as +#deep_merge+, but modifies +self+.
|
168
|
+
#
|
169
|
+
#--
|
170
|
+
# Implemented by ActiveSupport::DeepMergeable#deep_merge!.
|
171
|
+
|
137
172
|
##
|
138
173
|
# :method: as_json
|
139
174
|
#
|
@@ -160,12 +195,12 @@ module ActionController
|
|
160
195
|
# Returns true if the parameters have no key/value pairs.
|
161
196
|
|
162
197
|
##
|
163
|
-
# :method:
|
198
|
+
# :method: exclude?
|
164
199
|
#
|
165
200
|
# :call-seq:
|
166
|
-
#
|
201
|
+
# exclude?(key)
|
167
202
|
#
|
168
|
-
# Returns true if the given
|
203
|
+
# Returns true if the given key is not present in the parameters.
|
169
204
|
|
170
205
|
##
|
171
206
|
# :method: include?
|
@@ -191,22 +226,7 @@ module ActionController
|
|
191
226
|
#
|
192
227
|
# Returns the content of the parameters as a string.
|
193
228
|
|
194
|
-
|
195
|
-
# :method: value?
|
196
|
-
#
|
197
|
-
# :call-seq:
|
198
|
-
# value?(value)
|
199
|
-
#
|
200
|
-
# Returns true if the given value is present for some key in the parameters.
|
201
|
-
|
202
|
-
##
|
203
|
-
# :method: values
|
204
|
-
#
|
205
|
-
# :call-seq:
|
206
|
-
# values()
|
207
|
-
#
|
208
|
-
# Returns a new array of the values of the parameters.
|
209
|
-
delegate :keys, :values, :has_value?, :value?, :empty?, :include?,
|
229
|
+
delegate :keys, :empty?, :exclude?, :include?,
|
210
230
|
:as_json, :to_s, :each_key, to: :@parameters
|
211
231
|
|
212
232
|
alias_method :has_key?, :include?
|
@@ -222,13 +242,15 @@ module ActionController
|
|
222
242
|
# config.action_controller.always_permitted_parameters = %w( controller action format )
|
223
243
|
cattr_accessor :always_permitted_parameters, default: %w( controller action )
|
224
244
|
|
245
|
+
cattr_accessor :allow_deprecated_parameters_hash_equality, default: true, instance_accessor: false
|
246
|
+
|
225
247
|
class << self
|
226
248
|
def nested_attribute?(key, value) # :nodoc:
|
227
249
|
/\A-?\d+\z/.match?(key) && (value.is_a?(Hash) || value.is_a?(Parameters))
|
228
250
|
end
|
229
251
|
end
|
230
252
|
|
231
|
-
# Returns a new
|
253
|
+
# Returns a new +ActionController::Parameters+ instance.
|
232
254
|
# Also, sets the +permitted+ attribute to the default value of
|
233
255
|
# <tt>ActionController::Parameters.permit_all_parameters</tt>.
|
234
256
|
#
|
@@ -245,6 +267,12 @@ module ActionController
|
|
245
267
|
# params.permitted? # => true
|
246
268
|
# Person.new(params) # => #<Person id: nil, name: "Francesco">
|
247
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
|
+
|
248
276
|
@parameters = parameters.with_indifferent_access
|
249
277
|
@logging_context = logging_context
|
250
278
|
@permitted = self.class.permit_all_parameters
|
@@ -256,7 +284,20 @@ module ActionController
|
|
256
284
|
if other.respond_to?(:permitted?)
|
257
285
|
permitted? == other.permitted? && parameters == other.parameters
|
258
286
|
else
|
259
|
-
|
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
|
260
301
|
end
|
261
302
|
end
|
262
303
|
|
@@ -282,9 +323,9 @@ module ActionController
|
|
282
323
|
#
|
283
324
|
# safe_params = params.permit(:name)
|
284
325
|
# safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
|
285
|
-
def to_h
|
326
|
+
def to_h(&block)
|
286
327
|
if permitted?
|
287
|
-
convert_parameters_to_hashes(@parameters, :to_h)
|
328
|
+
convert_parameters_to_hashes(@parameters, :to_h, &block)
|
288
329
|
else
|
289
330
|
raise UnfilteredParameters
|
290
331
|
end
|
@@ -374,6 +415,11 @@ module ActionController
|
|
374
415
|
self
|
375
416
|
end
|
376
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
|
+
|
377
423
|
# Attribute that keeps track of converted arrays, if any, to avoid double
|
378
424
|
# looping in the common use case permit + mass-assignment. Defined in a
|
379
425
|
# method to instantiate it only if needed.
|
@@ -480,7 +526,7 @@ module ActionController
|
|
480
526
|
|
481
527
|
alias :required :require
|
482
528
|
|
483
|
-
# Returns a new
|
529
|
+
# Returns a new +ActionController::Parameters+ instance that
|
484
530
|
# includes only the given +filters+ and sets the +permitted+ attribute
|
485
531
|
# for the object to +true+. This is useful for limiting which attributes
|
486
532
|
# should be allowed for mass updating.
|
@@ -665,7 +711,7 @@ module ActionController
|
|
665
711
|
@parameters.dig(*keys)
|
666
712
|
end
|
667
713
|
|
668
|
-
# Returns a new
|
714
|
+
# Returns a new +ActionController::Parameters+ instance that
|
669
715
|
# includes only the given +keys+. If the given +keys+
|
670
716
|
# don't exist, returns an empty hash.
|
671
717
|
#
|
@@ -676,14 +722,14 @@ module ActionController
|
|
676
722
|
new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
|
677
723
|
end
|
678
724
|
|
679
|
-
# Returns the current
|
725
|
+
# Returns the current +ActionController::Parameters+ instance which
|
680
726
|
# contains only the given +keys+.
|
681
727
|
def slice!(*keys)
|
682
728
|
@parameters.slice!(*keys)
|
683
729
|
self
|
684
730
|
end
|
685
731
|
|
686
|
-
# Returns a new
|
732
|
+
# Returns a new +ActionController::Parameters+ instance that
|
687
733
|
# filters out the given +keys+.
|
688
734
|
#
|
689
735
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
@@ -692,6 +738,7 @@ module ActionController
|
|
692
738
|
def except(*keys)
|
693
739
|
new_instance_with_inherited_permitted_status(@parameters.except(*keys))
|
694
740
|
end
|
741
|
+
alias_method :without, :except
|
695
742
|
|
696
743
|
# Removes and returns the key/value pairs matching the given keys.
|
697
744
|
#
|
@@ -702,7 +749,7 @@ module ActionController
|
|
702
749
|
new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
|
703
750
|
end
|
704
751
|
|
705
|
-
# Returns a new
|
752
|
+
# Returns a new +ActionController::Parameters+ instance with the results of
|
706
753
|
# running +block+ once for every value. The keys are unchanged.
|
707
754
|
#
|
708
755
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
@@ -716,14 +763,14 @@ module ActionController
|
|
716
763
|
end
|
717
764
|
|
718
765
|
# Performs values transformation and returns the altered
|
719
|
-
#
|
766
|
+
# +ActionController::Parameters+ instance.
|
720
767
|
def transform_values!
|
721
768
|
return to_enum(:transform_values!) unless block_given?
|
722
769
|
@parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
|
723
770
|
self
|
724
771
|
end
|
725
772
|
|
726
|
-
# Returns a new
|
773
|
+
# Returns a new +ActionController::Parameters+ instance with the
|
727
774
|
# results of running +block+ once for every key. The values are unchanged.
|
728
775
|
def transform_keys(&block)
|
729
776
|
return to_enum(:transform_keys) unless block_given?
|
@@ -733,14 +780,14 @@ module ActionController
|
|
733
780
|
end
|
734
781
|
|
735
782
|
# Performs keys transformation and returns the altered
|
736
|
-
#
|
783
|
+
# +ActionController::Parameters+ instance.
|
737
784
|
def transform_keys!(&block)
|
738
785
|
return to_enum(:transform_keys!) unless block_given?
|
739
786
|
@parameters.transform_keys!(&block)
|
740
787
|
self
|
741
788
|
end
|
742
789
|
|
743
|
-
# Returns a new
|
790
|
+
# Returns a new +ActionController::Parameters+ instance with the
|
744
791
|
# results of running +block+ once for every key. This includes the keys
|
745
792
|
# from the root hash and from all nested hashes and arrays. The values are unchanged.
|
746
793
|
def deep_transform_keys(&block)
|
@@ -749,7 +796,7 @@ module ActionController
|
|
749
796
|
)
|
750
797
|
end
|
751
798
|
|
752
|
-
# Returns the same
|
799
|
+
# Returns the same +ActionController::Parameters+ instance with
|
753
800
|
# changed keys. This includes the keys from the root hash and from all
|
754
801
|
# nested hashes and arrays. The values are unchanged.
|
755
802
|
def deep_transform_keys!(&block)
|
@@ -765,7 +812,7 @@ module ActionController
|
|
765
812
|
convert_value_to_parameters(@parameters.delete(key, &block))
|
766
813
|
end
|
767
814
|
|
768
|
-
# Returns a new
|
815
|
+
# Returns a new +ActionController::Parameters+ instance with only
|
769
816
|
# items that the block evaluates to true.
|
770
817
|
def select(&block)
|
771
818
|
new_instance_with_inherited_permitted_status(@parameters.select(&block))
|
@@ -778,7 +825,7 @@ module ActionController
|
|
778
825
|
end
|
779
826
|
alias_method :keep_if, :select!
|
780
827
|
|
781
|
-
# Returns a new
|
828
|
+
# Returns a new +ActionController::Parameters+ instance with items
|
782
829
|
# that the block evaluates to true removed.
|
783
830
|
def reject(&block)
|
784
831
|
new_instance_with_inherited_permitted_status(@parameters.reject(&block))
|
@@ -791,7 +838,7 @@ module ActionController
|
|
791
838
|
end
|
792
839
|
alias_method :delete_if, :reject!
|
793
840
|
|
794
|
-
# Returns a new
|
841
|
+
# Returns a new +ActionController::Parameters+ instance with +nil+ values removed.
|
795
842
|
def compact
|
796
843
|
new_instance_with_inherited_permitted_status(@parameters.compact)
|
797
844
|
end
|
@@ -801,7 +848,7 @@ module ActionController
|
|
801
848
|
self if @parameters.compact!
|
802
849
|
end
|
803
850
|
|
804
|
-
# Returns a new
|
851
|
+
# Returns a new +ActionController::Parameters+ instance without the blank values.
|
805
852
|
# Uses Object#blank? for determining if a value is blank.
|
806
853
|
def compact_blank
|
807
854
|
reject { |_k, v| v.blank? }
|
@@ -813,13 +860,20 @@ module ActionController
|
|
813
860
|
reject! { |_k, v| v.blank? }
|
814
861
|
end
|
815
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
|
+
|
816
870
|
# Returns values that were assigned to the given +keys+. Note that all the
|
817
|
-
# +Hash+ objects will be converted to
|
871
|
+
# +Hash+ objects will be converted to +ActionController::Parameters+.
|
818
872
|
def values_at(*keys)
|
819
873
|
convert_value_to_parameters(@parameters.values_at(*keys))
|
820
874
|
end
|
821
875
|
|
822
|
-
# Returns a new
|
876
|
+
# Returns a new +ActionController::Parameters+ instance with all keys from
|
823
877
|
# +other_hash+ merged into current hash.
|
824
878
|
def merge(other_hash)
|
825
879
|
new_instance_with_inherited_permitted_status(
|
@@ -827,14 +881,21 @@ module ActionController
|
|
827
881
|
)
|
828
882
|
end
|
829
883
|
|
830
|
-
|
884
|
+
##
|
885
|
+
# :call-seq: merge!(other_hash)
|
886
|
+
#
|
887
|
+
# Returns the current +ActionController::Parameters+ instance with
|
831
888
|
# +other_hash+ merged into current hash.
|
832
|
-
def merge!(other_hash)
|
833
|
-
@parameters.merge!(other_hash.to_h)
|
889
|
+
def merge!(other_hash, &block)
|
890
|
+
@parameters.merge!(other_hash.to_h, &block)
|
834
891
|
self
|
835
892
|
end
|
836
893
|
|
837
|
-
|
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
|
838
899
|
# from current hash merged into +other_hash+.
|
839
900
|
def reverse_merge(other_hash)
|
840
901
|
new_instance_with_inherited_permitted_status(
|
@@ -843,7 +904,7 @@ module ActionController
|
|
843
904
|
end
|
844
905
|
alias_method :with_defaults, :reverse_merge
|
845
906
|
|
846
|
-
# Returns the current
|
907
|
+
# Returns the current +ActionController::Parameters+ instance with
|
847
908
|
# current hash merged into +other_hash+.
|
848
909
|
def reverse_merge!(other_hash)
|
849
910
|
@parameters.merge!(other_hash.to_h) { |key, left, right| left }
|
@@ -900,6 +961,22 @@ module ActionController
|
|
900
961
|
end
|
901
962
|
end
|
902
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
|
+
|
903
980
|
protected
|
904
981
|
attr_reader :parameters
|
905
982
|
|
@@ -922,14 +999,15 @@ module ActionController
|
|
922
999
|
end
|
923
1000
|
end
|
924
1001
|
|
925
|
-
def convert_parameters_to_hashes(value, using)
|
1002
|
+
def convert_parameters_to_hashes(value, using, &block)
|
926
1003
|
case value
|
927
1004
|
when Array
|
928
1005
|
value.map { |v| convert_parameters_to_hashes(v, using) }
|
929
1006
|
when Hash
|
930
|
-
value.transform_values do |v|
|
1007
|
+
transformed = value.transform_values do |v|
|
931
1008
|
convert_parameters_to_hashes(v, using)
|
932
|
-
end
|
1009
|
+
end
|
1010
|
+
(block_given? ? transformed.to_h(&block) : transformed).with_indifferent_access
|
933
1011
|
when Parameters
|
934
1012
|
value.send(using)
|
935
1013
|
else
|
@@ -1112,6 +1190,8 @@ module ActionController
|
|
1112
1190
|
case element
|
1113
1191
|
when ->(e) { permitted_scalar?(e) }
|
1114
1192
|
sanitized << element
|
1193
|
+
when Array
|
1194
|
+
sanitized << permit_any_in_array(element)
|
1115
1195
|
when Parameters
|
1116
1196
|
sanitized << permit_any_in_parameters(element)
|
1117
1197
|
else
|
@@ -1127,7 +1207,7 @@ module ActionController
|
|
1127
1207
|
end
|
1128
1208
|
end
|
1129
1209
|
|
1130
|
-
#
|
1210
|
+
# = Strong \Parameters
|
1131
1211
|
#
|
1132
1212
|
# It provides an interface for protecting attributes from end-user
|
1133
1213
|
# assignment. This makes Action Controller parameters forbidden
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionController
|
4
|
+
# = Action Controller \UrlFor
|
5
|
+
#
|
4
6
|
# Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
|
5
7
|
# the <tt>_routes</tt> method. Otherwise, an exception will be raised.
|
6
8
|
#
|
@@ -25,6 +27,11 @@ module ActionController
|
|
25
27
|
|
26
28
|
include AbstractController::UrlFor
|
27
29
|
|
30
|
+
def initialize(...)
|
31
|
+
super
|
32
|
+
@_url_options = nil
|
33
|
+
end
|
34
|
+
|
28
35
|
def url_options
|
29
36
|
@_url_options ||= {
|
30
37
|
host: request.host,
|
@@ -4,6 +4,8 @@ require "active_support/core_ext/array/extract_options"
|
|
4
4
|
require "action_dispatch/middleware/stack"
|
5
5
|
|
6
6
|
module ActionController
|
7
|
+
# = Action Controller \MiddlewareStack
|
8
|
+
#
|
7
9
|
# Extend ActionDispatch middleware stack to make it aware of options
|
8
10
|
# allowing the following syntax in controllers:
|
9
11
|
#
|
@@ -58,7 +60,9 @@ module ActionController
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
#
|
63
|
+
# = Action Controller \Metal
|
64
|
+
#
|
65
|
+
# +ActionController::Metal+ is the simplest possible controller, providing a
|
62
66
|
# valid Rack interface without the additional niceties provided by
|
63
67
|
# ActionController::Base.
|
64
68
|
#
|
@@ -78,9 +82,9 @@ module ActionController
|
|
78
82
|
# The +action+ method returns a valid Rack application for the \Rails
|
79
83
|
# router to dispatch to.
|
80
84
|
#
|
81
|
-
# == Rendering Helpers
|
85
|
+
# == \Rendering \Helpers
|
82
86
|
#
|
83
|
-
#
|
87
|
+
# +ActionController::Metal+ by default provides no utilities for rendering
|
84
88
|
# views, partials, or other responses aside from explicitly calling of
|
85
89
|
# <tt>response_body=</tt>, <tt>content_type=</tt>, and <tt>status=</tt>. To
|
86
90
|
# add the render helpers you're used to having in a normal controller, you
|
@@ -96,7 +100,7 @@ module ActionController
|
|
96
100
|
# end
|
97
101
|
# end
|
98
102
|
#
|
99
|
-
# == Redirection Helpers
|
103
|
+
# == Redirection \Helpers
|
100
104
|
#
|
101
105
|
# To add redirection helpers to your metal controller, do the following:
|
102
106
|
#
|
@@ -109,7 +113,7 @@ module ActionController
|
|
109
113
|
# end
|
110
114
|
# end
|
111
115
|
#
|
112
|
-
# == Other Helpers
|
116
|
+
# == Other \Helpers
|
113
117
|
#
|
114
118
|
# You can refer to the modules included in ActionController::Base to see
|
115
119
|
# other features you can bring into your metal controller.
|
@@ -118,8 +122,8 @@ module ActionController
|
|
118
122
|
abstract!
|
119
123
|
|
120
124
|
# Returns the last part of the controller's name, underscored, without the ending
|
121
|
-
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
|
122
|
-
# Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
|
125
|
+
# <tt>Controller</tt>. For instance, +PostsController+ returns <tt>posts</tt>.
|
126
|
+
# Namespaces are left out, so +Admin::PostsController+ returns <tt>posts</tt> as well.
|
123
127
|
#
|
124
128
|
# ==== Returns
|
125
129
|
# * <tt>string</tt>
|
@@ -137,20 +141,53 @@ module ActionController
|
|
137
141
|
false
|
138
142
|
end
|
139
143
|
|
144
|
+
class << self
|
145
|
+
private
|
146
|
+
def inherited(subclass)
|
147
|
+
super
|
148
|
+
subclass.middleware_stack = middleware_stack.dup
|
149
|
+
subclass.class_eval do
|
150
|
+
@controller_name = nil
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
140
155
|
# Delegates to the class's ::controller_name.
|
141
156
|
def controller_name
|
142
157
|
self.class.controller_name
|
143
158
|
end
|
144
159
|
|
145
|
-
|
160
|
+
##
|
161
|
+
# :attr_reader: request
|
162
|
+
#
|
163
|
+
# The ActionDispatch::Request instance for the current request.
|
164
|
+
attr_internal :request
|
165
|
+
|
166
|
+
##
|
167
|
+
# :attr_reader: response
|
168
|
+
#
|
169
|
+
# The ActionDispatch::Response instance for the current response.
|
170
|
+
attr_internal_reader :response
|
171
|
+
|
172
|
+
##
|
173
|
+
# The ActionDispatch::Request::Session instance for the current request.
|
174
|
+
# See further details in the
|
175
|
+
# {Active Controller Session guide}[https://guides.rubyonrails.org/action_controller_overview.html#session].
|
146
176
|
delegate :session, to: "@_request"
|
147
|
-
|
177
|
+
|
178
|
+
##
|
179
|
+
# Delegates to ActionDispatch::Response#headers.
|
180
|
+
delegate :headers, to: "@_response"
|
181
|
+
|
182
|
+
delegate :status=, :location=, :content_type=,
|
148
183
|
:status, :location, :content_type, :media_type, to: "@_response"
|
149
184
|
|
150
185
|
def initialize
|
151
186
|
@_request = nil
|
152
187
|
@_response = nil
|
188
|
+
@_response_body = nil
|
153
189
|
@_routes = nil
|
190
|
+
@_params = nil
|
154
191
|
super
|
155
192
|
end
|
156
193
|
|
@@ -164,17 +201,19 @@ module ActionController
|
|
164
201
|
|
165
202
|
alias :response_code :status # :nodoc:
|
166
203
|
|
167
|
-
# Basic url_for that can be overridden for more robust functionality.
|
204
|
+
# Basic \url_for that can be overridden for more robust functionality.
|
168
205
|
def url_for(string)
|
169
206
|
string
|
170
207
|
end
|
171
208
|
|
172
209
|
def response_body=(body)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
210
|
+
if body
|
211
|
+
body = [body] if body.is_a?(String)
|
212
|
+
response.body = body
|
213
|
+
super
|
214
|
+
else
|
215
|
+
response.reset_body!
|
216
|
+
end
|
178
217
|
end
|
179
218
|
|
180
219
|
# Tests if render or redirect has already happened.
|
@@ -191,9 +230,22 @@ module ActionController
|
|
191
230
|
end
|
192
231
|
|
193
232
|
def set_response!(response) # :nodoc:
|
233
|
+
if @_response
|
234
|
+
_, _, body = @_response
|
235
|
+
body.close if body.respond_to?(:close)
|
236
|
+
end
|
237
|
+
|
194
238
|
@_response = response
|
195
239
|
end
|
196
240
|
|
241
|
+
# Assign the response and mark it as committed. No further processing will occur.
|
242
|
+
def response=(response)
|
243
|
+
set_response!(response)
|
244
|
+
|
245
|
+
# Force `performed?` to return true:
|
246
|
+
@_response_body = true
|
247
|
+
end
|
248
|
+
|
197
249
|
def set_request!(request) # :nodoc:
|
198
250
|
@_request = request
|
199
251
|
@_request.controller_instance = self
|
@@ -209,11 +261,6 @@ module ActionController
|
|
209
261
|
|
210
262
|
class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
|
211
263
|
|
212
|
-
def self.inherited(base) # :nodoc:
|
213
|
-
base.middleware_stack = middleware_stack.dup
|
214
|
-
super
|
215
|
-
end
|
216
|
-
|
217
264
|
class << self
|
218
265
|
# Pushes the given Rack middleware and its arguments to the bottom of the
|
219
266
|
# middleware stack.
|
@@ -222,7 +269,18 @@ module ActionController
|
|
222
269
|
end
|
223
270
|
end
|
224
271
|
|
225
|
-
#
|
272
|
+
# The middleware stack used by this controller.
|
273
|
+
#
|
274
|
+
# By default uses a variation of ActionDispatch::MiddlewareStack which
|
275
|
+
# allows for the following syntax:
|
276
|
+
#
|
277
|
+
# class PostsController < ApplicationController
|
278
|
+
# use AuthenticationMiddleware, except: [:index, :show]
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# Read more about {Rails middleware
|
282
|
+
# stack}[https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack]
|
283
|
+
# in the guides.
|
226
284
|
def self.middleware
|
227
285
|
middleware_stack
|
228
286
|
end
|