I realized that sometimes a nested form fail to destroy a child
in rails 3.0.3.
It happens when the children are not loaded and the parent is
assigned the attributes.
I narrowed down the problem code.
activerecord-3.0.3/lib/active_record/nested_attributes.rb
line# 376:
association.send(:add_record_to_target_with_callbacks,
existing_record) if association.loaded? &&
!call_reject_if(association_name, attributes)
The line was changed from rails 3.0.0.
Here's how I tested it in console.
(I intentionally removed some outputs for simplicity.)
Loading development environment (Rails 3.0.3)
ruby-1.8.7-p302 > post=Post.find 204
ruby-1.8.7-p302 > post.attachments.loaded?
=> false
ruby-1.8.7-p302 >
post.attributes={"attachments_attributes"=>{"0"=>{"id"=>"44",
"_destroy"=>"1"}}}
ruby-1.8.7-p302 > post.save
=> true
ruby-1.8.7-p302 > post.attachments.map { |i| i.id }.join(", ")
=> "44, 45, 46, 47, 48, 49" #44 is still there.
ruby-1.8.7-p302 >
post.attributes={"attachments_attributes"=>{"0"=>{"id"=>"44",
"_destroy"=>"1"}}}
# Now I try to destroy it again when the attachments are loaded.
ruby-1.8.7-p302 > post.save
=> true
ruby-1.8.7-p302 > post.attachments.reload
# To make sure that attachments are reloaded after the change.
ruby-1.8.7-p302 > post.attachments.map { |i| i.id }.join(", ")
=> "45, 46, 47, 48, 49" # Now 44 is gone.
The problem doesn't happen in rails 3.0.0.
Edited by Rohit Arondekar
for formatting.