James Coleman
2012-Feb-23 17:51 UTC
Bug in nested_attributes_for: question about best way to patch
I''ve discovered what I''m pretty confident is unexpected behavior in accepts_nested_attributes_for, and am developing a patch, but I''ve encountered a question about how the core team would prefer the implementation to look. Here''s the bug: when assigning to a belongs_to relationship (and I believe one-to-one, but I haven''t verified yet) if you mark the association for destruction the association is not unset yet the record is deleted. This result in both unexpected behavior: the association seems to still be present in memory after the update, and in invalid data being saved (foreign key violations) because the parent record saved still has the association_id set even though the associated record has been destroyed. Here is a test demonstrating the error and the expectations: def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @ship.pirate.destroy [1, ''1'', true, ''true''].each do |truth| pirate = @ship.reload.create_pirate(:catchphrase => ''Arr'') @ship.update_attributes(:pirate_attributes => { :id => pirate.id, :_destroy => truth }) assert_raise(ActiveRecord::RecordNotFound) { pirate.reload } end end I''ve also a partial patch developed: http://pastie.org/3438962 The problem is that to trigger the record deletion, the association still needs to be there to be walked on the save call. I have two question: 1. Does everyone agree on the expected behavior? 2. What is the best implementation route: should I maintain a hidden list/hash on each object of associations that have been unset and marked for deletion to use both at saving and if someone resets the object? Or is that capability already essentially available in the change tracking? Or something different all-together. Something along these lines already has to be there because updating the has_many leaves the collection in memory without the marked-for- destruction records. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
James Coleman
2012-Mar-01 20:13 UTC
Re: Bug in nested_attributes_for: question about best way to patch
I discovered the bug is also with has_many items (contrary to my original post.) I''ve submitted this as a bug with test cases at https://github.com/rails/rails/issues/5235 I''d appreciate guidance on that issue. On Feb 23, 12:51 pm, James Coleman <jtc...@gmail.com> wrote:> I''ve discovered what I''m pretty confident is unexpected behavior in > accepts_nested_attributes_for, and am developing a patch, but I''ve > encountered a question about how the core team would prefer the > implementation to look. > > Here''s the bug: when assigning to a belongs_to relationship (and I > believe one-to-one, but I haven''t verified yet) if you mark the > association for destruction the association is not unset yet the > record is deleted. This result in both unexpected behavior: the > association seems to still be present in memory after the update, and > in invalid data being saved (foreign key violations) because the > parent record saved still has the association_id set even though the > associated record has been destroyed. > > Here is a test demonstrating the error and the expectations: > > def > test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destro y_is_truthy > @ship.pirate.destroy > [1, ''1'', true, ''true''].each do |truth| > pirate = @ship.reload.create_pirate(:catchphrase => ''Arr'') > @ship.update_attributes(:pirate_attributes => { :id => > pirate.id, :_destroy => truth }) > assert_raise(ActiveRecord::RecordNotFound) { pirate.reload } > end > end > > I''ve also a partial patch developed:http://pastie.org/3438962 > > The problem is that to trigger the record deletion, the association > still needs to be there to be walked on the save call. > > I have two question: > 1. Does everyone agree on the expected behavior? > 2. What is the best implementation route: should I maintain a hidden > list/hash on each object of associations that have been unset and > marked for deletion to use both at saving and if someone resets the > object? Or is that capability already essentially available in the > change tracking? Or something different all-together. > > Something along these lines already has to be there because updating > the has_many leaves the collection in memory without the marked-for- > destruction records.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.