From 68af63618223c238468af1afb093eb4ccc706761 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Sat, 18 Jul 2015 08:42:29 -0400 Subject: Ensure that `ActionController::Parameters` can still be passed to AR Since nested hashes are also instances of `ActionController::Parameters`, and we're explicitly looking to work with a hash for nested attributes, this caused breakage in several points. This is the minimum viable fix for the issue (and one that I'm not terribly fond of). I can't think of a better place to handle this at the moment. I'd prefer to use some sort of solution that doesn't special case AC::Parameters, but we can't use something like `to_h` or `to_a` since `Enumerable` adds both. While I've added a trivial test case for verifying this fix in isolation, we really need better integration coverage to prevent regressions like this in the future. We don't actually have a lot of great places for integration coverage at the moment, so I'm deferring it for now. Fixes #20922. --- activerecord/CHANGELOG.md | 7 +++++++ .../lib/active_record/nested_attributes.rb | 3 +++ activerecord/test/cases/nested_attributes_test.rb | 23 ++++++++++++++++++++++ 3 files changed, 33 insertions(+) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 237b07f653..47364325ea 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* Ensure that `ActionController::Parameters` can still be passed to nested + attributes. + + Fixes #20922. + + *Sean Griffin* + * Deprecate force association reload by passing a truthy argument to association method. diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index c942d0e265..c337e1d18f 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -386,6 +386,9 @@ module ActiveRecord # then the existing record will be marked for destruction. def assign_nested_attributes_for_one_to_one_association(association_name, attributes) options = self.nested_attributes_options[association_name] + if attributes.respond_to?(:permitted?) + attributes = attributes.to_h + end attributes = attributes.with_indifferent_access existing_record = send(association_name) diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index d72225f3d3..933dfac806 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -1064,4 +1064,27 @@ class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveR assert_not part.valid? assert_equal ["Ship name can't be blank"], part.errors.full_messages end + + class ProtectedParameters + def initialize(hash) + @hash = hash + end + + def permitted? + true + end + + def to_h + @hash + end + end + + test "strong params style objects can be assigned" do + params = { name: "Stern", ship_attributes: + ProtectedParameters.new(name: "The Black Rock") } + part = ShipPart.new(params) + + assert_equal "Stern", part.name + assert_equal "The Black Rock", part.ship.name + end end -- cgit v1.2.3