Nested Attributes For HABTM - Deleting The Right Record

In a many-to-many relationship, defined via has_and_belongs_to_many,
accepts_nested_attributes_for deletes the wrong record(s) when
marked_for_destruction? == true.

For example:

class Ho < AR
has_and_belongs_to_many :strolls, :join_table => :ho_strolls
accepts_nested_attributes_for :strolls, :allow_destroy => true
end

class Stroll < AR
has_and_belongs_to_many :hos, :join_table => :ho_strolls
end

attribs = {“1”=>{"_delete"=>“1”, :id=>“123”}}

h=Ho.first
h.strolls_attributes = attribs
h.save!

This will delete Stroll with an id of 123 from the join table and the
strolls table.
This is wrong. It should only be deleted from the ho_strolls table.
Though I believe there is a fix (or a debate still, maybe) on the way:
https://rails.lighthouseapp.com/projects/8994/tickets/2251-associationcollectiondestroy-should-only-delete-join-table-records

At any rate, I have the following work around. It assumes that I’ll
never delete a stroll from the strolls tables via a hoe. What do you
think?

class Ho < AR
has_and_belongs_to_many :strolls, :join_table => :ho_strolls
accepts_nested_attributes_for :strolls, :allow_destroy => true

def before_save
remove_marked_strolls
end

def remove_marked_strolls
marked = strolls.select { |stroll|
stroll.marked_for_destruction? }
marked.each { |stroll| stroll.delete(stroll) } #delete from join
table only
end
end

I though about doing:

class Stroll < AR

def unmark_for_deletion; @marked_for_deletion = false; end
end

And then unmarking in remove_marked_strolls, though this seems
superfluous since the records are remove from the collection the proxy
will never get to check for this condition and delete them from
strolls.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs