Merge pull request #50804 from joshuay03/consistently-raise-an-error-for-nested-attributes-args

[Fix #50803] Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer
This commit is contained in:
Jean Boussier 2024-01-19 13:29:01 +01:00 committed by GitHub
commit 44ef49c2d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 3 deletions

View File

@ -1,3 +1,11 @@
* Consistently raise an `ArgumentError` when passing an invalid argument to a nested attributes association writer.
Previously, this would only raise on collection associations and produce a generic error on singular associations.
Now, it will raise on both collection and singular associations.
*Joshua Young*
* Fix single quote escapes on default generated MySQL columns
MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.

View File

@ -421,10 +421,15 @@ module ActiveRecord
# update_only is true, and a <tt>:_destroy</tt> key set to a truthy value,
# then the existing record will be marked for destruction.
def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
options = nested_attributes_options[association_name]
if attributes.respond_to?(:permitted?)
attributes = attributes.to_h
end
unless attributes.is_a?(Hash)
raise ArgumentError, "Hash expected for `#{association_name}` attributes, got #{attributes.class.name}"
end
options = nested_attributes_options[association_name]
attributes = attributes.with_indifferent_access
existing_record = send(association_name)
@ -486,7 +491,7 @@ module ActiveRecord
end
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
raise ArgumentError, "Hash or Array expected for attribute `#{association_name}`, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
raise ArgumentError, "Hash or Array expected for `#{association_name}` attributes, got #{attributes_collection.class.name}"
end
check_record_limit!(options[:limit], attributes_collection)

View File

@ -422,6 +422,13 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
Pirate.accepts_nested_attributes_for :update_only_ship, update_only: true, allow_destroy: false
end
def test_should_raise_an_argument_error_if_something_other_than_a_hash_is_passed_in
exception = assert_raise ArgumentError do
@pirate.update(ship_attributes: "foo")
end
assert_equal "Hash expected for `ship` attributes, got String", exception.message
end
end
class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@ -598,6 +605,13 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
Ship.accepts_nested_attributes_for :update_only_pirate, update_only: true, allow_destroy: false
end
def test_should_raise_an_argument_error_if_something_other_than_a_hash_is_passed_in
exception = assert_raise ArgumentError do
@ship.update(pirate_attributes: "foo")
end
assert_equal "Hash expected for `pirate` attributes, got String", exception.message
end
end
module NestedAttributesOnACollectionAssociationTests
@ -768,7 +782,7 @@ module NestedAttributesOnACollectionAssociationTests
exception = assert_raise ArgumentError do
@pirate.public_send(association_setter, "foo")
end
assert_equal %{Hash or Array expected for attribute `#{@association_name}`, got String ("foo")}, exception.message
assert_equal %{Hash or Array expected for `#{@association_name}` attributes, got String}, exception.message
end
def test_should_work_with_update_as_well