accepts_nested_attributes_for and _destroy without checkboxes

I’ve never been a fan of using check boxes on a form to mark child records for deletion. It seems a little counter-intuitive for most users. While I do use accepts_nested_attributes to mark items for deletion upon save, I don’t use checkboxes.

On my forms, I prefer to delete any list item or table rows that are to be destroyed (after prompting the user to confirm they want these deleted) and then figure out what needs to be deleted upon save. Take as an example Organizations that have many PhoneNumbers associated with them.

We update an organization object as follows:

@organization=Organization.where(:id => params[:id]).first    

And then, before saving, perform the following for the nested attributes:

@organization.phone_numbers.each {|phone| phone.mark_for_destruction unless params[:organization][:phone_numbers_attributes] && params[:organization][:phone_numbers_attributes].detect {|k, v| v.detect {|fld, value| fld=="id" &&}} }

This effectively marks for deletion any phone numbers which belong to the organization, but were no longer present on the form when submitted (because the user asked to remove them with confirmation). I find it makes for a cleaner interface. Two caveats to note in the inner detect call:

  1. Make sure you compare your ID field as a string because the params hash will represent the values as strings.
  2. You want to compare the field name to “id” and not :id as it is not a symbol in the incoming params hash, but a literal string.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s