views:

623

answers:

2

So far, I've not been able to find a solution that is able to allow a form to interact with two models that have a one-to-many relationship. Say for example, a customer has many items.

Currently, I've implemented solutions using Javascript that enables users to add/remove rows to the item list. Let's keep it simple, we're creating new records here.

In improving this to be degradable, I've instead created a 'Add Item' button that commits a different value, so that in my create action, I'm able to capture the new attributes and add a new Item to the customer object.

However, since item is new and has no id, I have no way of removing a particular item. I've thought of using indexes and added post buttons/links to remove, but this sort of makes everything messy and I can't use my partial for collections. So I feel like it's a hack; is there a better alternative?

+1  A: 

railscasts episode #75 is about this, if I understand your question right.

I believe he creates the items and then marks them for deletion if the user regrets creating them.

imo this is the best way to handle the problem and there's advice to deal with validations.

I've seen that already, but it makes use of RJS to add/remove the items.
Jaryl
+1  A: 

You want to use accepts_nested_attributes_for. The Railscasts episode henrikloevborg mentions covers a method of doing this kind of thing that's been obsoleted by accepts_nested_attributes_for.

You can do it without accepts_nested_attributes_for. Which might be necessary if you don't want to upgrade to Rails 2.3.

In your javascript to remove an item, you should add a hidden field to the form called _delete with the value of true. Then in your controller. Ignore any new records with the _delete field, and destroy any existing ones.

All that's built in to accept_nested_attributes_for

Play around with the code in the complex-forms-exmample github repository. It's essentially the code from Railscast #75 updated to use the newer feature, accepts_nested_attributes_for.

You will notice that it doesn't use RJS to accomplish the dynamic addition/removal of records. Also compared to what you've been doing it creates on submit, not during a remote call. The automatic addition/deletion of items is handled using content_for tags to create a template stored in a javascript function and the Prototype library to modify a hidden field, which accepts_nested_attributes_for uses to destroy objects you want to remove.

EmFi
Yes, I know that the new features definitely make this possible. I guess I have to mark you as the correct answer anyways =)
Jaryl
The javascript contained in the complex-forms-example is a bit of a hack, but doesn't feel that way with all the helper methods to stream line it.
EmFi