Permalink
Browse files

Changed the assumption that accepts_nested_attributes_for will only b…

…e used with fields_for and the arbitrary decimal number keys. Instead, the code now looks to see if the key ends in _attributes, and deals with such hashes in a more acceptes_nested_attributes_for compliant way. Added a test to check that fields_attributes with random keys are processed properly.
  • Loading branch information...
1 parent 4c21c67 commit aa40d67f77c3d3c2e57aa025f3d34c09d9ba61b5 @HurricaneJames committed Jan 22, 2013
Showing with 26 additions and 4 deletions.
  1. +4 −4 lib/action_controller/parameters.rb
  2. +22 −0 test/parameters_permit_test.rb
@@ -167,7 +167,7 @@ def hash_filter(params, filter)
array_of_permitted_scalars_filter(params, key)
else
# Declaration {:user => :name} or {:user => [:name, :age, {:adress => ...}]}.
- params[key] = each_element(value) do |element|
+ params[key] = each_element(key, value) do |element|
if element.is_a?(Hash)
element = self.class.new(element) unless element.respond_to?(:permit)
element.permit(*Array.wrap(filter[key]))
@@ -177,11 +177,11 @@ def hash_filter(params, filter)
end
end
- def each_element(value)
+ def each_element(key, value)
if value.is_a?(Array)
value.map { |el| yield el }.compact
- # fields_for on an array of records uses numeric hash keys.
- elsif value.is_a?(Hash) && value.keys.all? { |k| k =~ /\A-?\d+\z/ }
+ # fields_for on an array of records will label the key as fields_attributes
+ elsif value.is_a?(Hash) && key =~ /_attributes$/
hash = value.class.new
value.each { |k,v| hash[k] = yield v }
hash
@@ -290,4 +290,26 @@ def assert_filtered_out(params, key)
assert_filtered_out permitted[:book][:authors_attributes]['-1'], :age_of_death
end
+
+ test "acceptes_nested_attributes_for_style_nested_params random keys" do
+ params = ActionController::Parameters.new({
+ :entry_form => {
+ :user_responses_attributes => {
+ :'first_name' => { :response => 'William', :entry_field_id => '52', :stip_me => 'Dali' },
+ :'last_name' => { :response => 'Shakespeare', :entry_field_id => '27' },
+ :'phone' => { :response => %w(this bad phone number should be stripped), :entry_field_id => '16' }
+ }
+ }
+ })
+ permitted = params.permit :entry_form => { :user_responses_attributes => [ :response, :entry_field_id ] }
+
+ assert_not_nil permitted[:entry_form][:user_responses_attributes]['first_name']
+ assert_not_nil permitted[:entry_form][:user_responses_attributes]['last_name']
+ assert_equal 'William', permitted[:entry_form][:user_responses_attributes]['first_name'][:response]
+ assert_equal 'Shakespeare', permitted[:entry_form][:user_responses_attributes]['last_name'][:response]
+
+ assert_filtered_out permitted[:entry_form][:user_responses_attributes]['phone'], :response
+ assert_filtered_out permitted[:entry_form][:user_responses_attributes]['first_name'], :strip_me
+ end
+
end

0 comments on commit aa40d67

Please sign in to comment.