aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrem Sichanugrist <s@sikac.hu>2014-07-25 16:16:58 -0400
committerPrem Sichanugrist <s@sikac.hu>2014-08-18 20:42:45 -0400
commitbd7f47190e942d1e514f702eafd1083909dd2884 (patch)
tree6312c54001b39727bbb1d1056a872ed46a7ef125
parent5109740c6be67047df56feb164012c3a1a3c619b (diff)
downloadrails-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
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb40
-rw-r--r--actionpack/test/controller/parameters/parameters_permit_test.rb21
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