Raise a RecordNotFound if an ID in nested attributes is given but doesn't return a record. [#2415 state:resolved]
This commit is contained in:
parent
b6264c43f4
commit
9550916903
@ -288,6 +288,10 @@ def assign_nested_attributes_for_one_to_one_association(association_name, attrib
|
||||
if check_existing_record && (record = send(association_name)) &&
|
||||
(options[:update_only] || record.id.to_s == attributes['id'].to_s)
|
||||
assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy])
|
||||
|
||||
elsif attributes['id']
|
||||
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
||||
|
||||
elsif !reject_new_record?(association_name, attributes)
|
||||
method = "build_#{association_name}"
|
||||
if respond_to?(method)
|
||||
@ -349,6 +353,8 @@ def assign_nested_attributes_for_collection_association(association_name, attrib
|
||||
end
|
||||
elsif existing_record = send(association_name).detect { |record| record.id.to_s == attributes['id'].to_s }
|
||||
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
||||
else
|
||||
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -383,5 +389,10 @@ def call_reject_if(association_name, attributes)
|
||||
callback.call(attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def raise_nested_attributes_record_not_found(association_name, record_id)
|
||||
reflection = self.class.reflect_on_association(association_name)
|
||||
raise RecordNotFound, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -173,6 +173,12 @@ def test_should_modify_an_existing_record_if_there_is_a_matching_id
|
||||
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
|
||||
end
|
||||
|
||||
def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}" do
|
||||
@pirate.ship_attributes = { :id => 1234567890 }
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_take_a_hash_with_string_keys_and_update_the_associated_model
|
||||
@pirate.reload.ship_attributes = { 'id' => @ship.id, 'name' => 'Davy Jones Gold Dagger' }
|
||||
|
||||
@ -266,6 +272,8 @@ def test_should_update_existing_when_update_only_is_true_and_no_id_is_given
|
||||
end
|
||||
|
||||
class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
|
||||
include AssertRaiseWithMessage
|
||||
|
||||
def setup
|
||||
@ship = Ship.new(:name => 'Nights Dirty Lightning')
|
||||
@pirate = @ship.build_pirate(:catchphrase => 'Aye')
|
||||
@ -320,6 +328,12 @@ def test_should_modify_an_existing_record_if_there_is_a_matching_id
|
||||
assert_equal 'Arr', @ship.pirate.catchphrase
|
||||
end
|
||||
|
||||
def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}" do
|
||||
@ship.pirate_attributes = { :id => 1234567890 }
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_take_a_hash_with_string_keys_and_update_the_associated_model
|
||||
@ship.reload.pirate_attributes = { 'id' => @pirate.id, 'catchphrase' => 'Arr' }
|
||||
|
||||
@ -381,10 +395,6 @@ def test_should_automatically_enable_autosave_on_the_association
|
||||
assert Ship.reflect_on_association(:pirate).options[:autosave]
|
||||
end
|
||||
|
||||
def test_should_accept_update_only_option
|
||||
@ship.update_attribute(:update_only_pirate_attributes, { :id => @pirate.ship.id, :catchphrase => 'Arr' })
|
||||
end
|
||||
|
||||
def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true
|
||||
@pirate.delete
|
||||
assert_difference('Pirate.count', 1) do
|
||||
@ -457,6 +467,12 @@ def test_should_take_a_hash_with_composite_id_keys_and_assign_the_attributes_to_
|
||||
assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.name, @child_2.name]
|
||||
end
|
||||
|
||||
def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}" do
|
||||
@pirate.attributes = { association_getter => [{ :id => 1234567890 }] }
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_automatically_build_new_associated_models_for_each_entry_in_a_hash_where_the_id_is_missing
|
||||
@pirate.send(@association_name).destroy_all
|
||||
@pirate.reload.attributes = {
|
||||
|
Loading…
Reference in New Issue
Block a user