Trust Object#dup in ActionController::Parameters, using #initialize_copy to manually duplicate the underlying parameters hash

It looks like `ActionController::Parameters#dup` is leftover from when the class inherited from `Hash`. We can just trust `#dup`, which already copies the `@permitted` instance variable (confirmed by tests). We still define a `#initialize_copy` to make `@parameters` a copy that can be mutated without affecting the original instance.
This commit is contained in:
Tim Rogers 2016-07-08 17:48:21 +01:00
parent ba3dd5ca04
commit 9607059569
2 changed files with 20 additions and 16 deletions

@ -572,20 +572,6 @@ def values_at(*keys)
convert_value_to_parameters(@parameters.values_at(*keys))
end
# Returns an exact copy of the <tt>ActionController::Parameters</tt>
# instance. +permitted+ state is kept on the duped object.
#
# params = ActionController::Parameters.new(a: 1)
# params.permit!
# params.permitted? # => true
# copy_params = params.dup # => <ActionController::Parameters {"a"=>1} permitted: true>
# copy_params.permitted? # => true
def dup
super.tap do |duplicate|
duplicate.permitted = @permitted
end
end
# Returns a new <tt>ActionController::Parameters</tt> with all keys from
# +other_hash+ merges into current hash.
def merge(other_hash)
@ -786,7 +772,7 @@ def hash_filter(params, filter)
def initialize_copy(source)
super
@parameters = source.instance_variable_get(:@parameters).dup
@parameters = @parameters.dup
end
end

@ -17,9 +17,27 @@ class ParametersDupTest < ActiveSupport::TestCase
)
end
test "changes on a duplicate do not affect the original" do
test "a duplicate maintains the original's permitted status" do
@params.permit!
dupped_params = @params.dup
assert dupped_params.permitted?
end
test "a duplicate maintains the original's parameters" do
@params.permit!
dupped_params = @params.dup
assert_equal @params.to_h, dupped_params.to_h
end
test "changes to a duplicate's parameters do not affect the original" do
dupped_params = @params.dup
dupped_params.delete(:person)
assert_not_equal @params, dupped_params
end
test "changes tp a duplicate's permitted status do not affect the original" do
dupped_params = @params.dup
dupped_params.permit!
assert_not_equal @params, dupped_params
end
end