actionpack 7.0.8 → 7.1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +360 -353
- 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 +7 -4
- 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 +40 -18
- 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 +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +64 -28
@@ -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
|