diff options
author | Prem Sichanugrist <s@sikac.hu> | 2014-07-25 16:16:58 -0400 |
---|---|---|
committer | Prem Sichanugrist <s@sikac.hu> | 2014-08-18 20:42:45 -0400 |
commit | bd7f47190e942d1e514f702eafd1083909dd2884 (patch) | |
tree | 6312c54001b39727bbb1d1056a872ed46a7ef125 /actionpack | |
parent | 5109740c6be67047df56feb164012c3a1a3c619b (diff) | |
download | rails-bd7f47190e942d1e514f702eafd1083909dd2884.tar.gz rails-bd7f47190e942d1e514f702eafd1083909dd2884.tar.bz2 rails-bd7f47190e942d1e514f702eafd1083909dd2884.zip |
Add missing `Hash` methods to `AC::Parameters`
This is to make sure that `permitted` status is maintained on the
resulting object.
I found these methods that needs to be redefined by looking for
`self.class.new` in the code.
* extract!
* transform_keys
* transform_values
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_controller/metal/strong_parameters.rb | 40 | ||||
-rw-r--r-- | actionpack/test/controller/parameters/parameters_permit_test.rb | 21 |
2 files changed, 61 insertions, 0 deletions
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 764474ad4e..02652a84b3 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -355,6 +355,46 @@ module ActionController end end + # Removes and returns the key/value pairs matching the given keys. + # + # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) + # params.extract!(:a, :b) # => {"a"=>1, "b"=>2} + # params # => {"c"=>3} + def extract!(*keys) + self.class.new(super).tap do |new_instance| + new_instance.permitted = @permitted + end + end + + # Returns a new <tt>ActionController::Parameters</tt> with the results of + # running +block+ once for every value. The keys are unchanged. + # + # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) + # params.transform_values { |x| x * 2 } + # # => {"a"=>2, "b"=>4, "c"=>6} + def transform_values + if block_given? + self.class.new(super).tap do |new_instance| + new_instance.permitted = @permitted + end + else + super + end + end + + # This method is here only to make sure that the returned object has the + # correct +permitted+ status. It should not matter since the parent of + # this object is +HashWithIndifferentAccess+ + def transform_keys # :nodoc: + if block_given? + self.class.new(super).tap do |new_instance| + new_instance.permitted = @permitted + end + else + super + end + end + # Returns an exact copy of the <tt>ActionController::Parameters</tt> # instance. +permitted+ state is kept on the duped object. # diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index c8cc654afd..b9d2145eb4 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -1,6 +1,7 @@ require 'abstract_unit' require 'action_dispatch/http/upload' require 'action_controller/metal/strong_parameters' +require 'active_support/core_ext/hash/transform_values' class ParametersPermitTest < ActiveSupport::TestCase def assert_filtered_out(params, key) @@ -204,6 +205,9 @@ class ParametersPermitTest < ActiveSupport::TestCase assert !@params.fetch(:person).permitted? assert !@params.values_at(:person).first.permitted? + + assert !@params.transform_keys { |k| k }.permitted? + assert !@params.transform_values { |v| v }.permitted? end test "permitted is sticky on accessors" do @@ -217,17 +221,34 @@ class ParametersPermitTest < ActiveSupport::TestCase assert @params.fetch(:person).permitted? assert @params.values_at(:person).first.permitted? + + assert @params.transform_keys { |k| k }.permitted? + assert @params.transform_values { |v| v }.permitted? end test "not permitted is sticky on mutators" do assert !@params.delete_if { |k| k == "person" }.permitted? assert !@params.keep_if { |k,v| k == "person" }.permitted? + + assert !@params.slice!(:person).permitted? + + assert !@params.extract!(:person).permitted? + + assert !@params.transform_keys! { |k| k }.permitted? + assert !@params.transform_values! { |v| v }.permitted? end test "permitted is sticky on mutators" do @params.permit! assert @params.delete_if { |k| k == "person" }.permitted? assert @params.keep_if { |k,v| k == "person" }.permitted? + + assert @params.slice!(:person).permitted? + + assert @params.extract!(:person).permitted? + + assert @params.transform_keys! { |k| k }.permitted? + assert @params.transform_values! { |v| v }.permitted? end test "not permitted is sticky beyond merges" do |