Emilio Tagua wrote:> The question would be, is there a way of naming the fields and use
> form_for :contact and send and hash/array of these lines and add them
> as new relationships.
> 
> I read about parsing something like contact[phones][][number] but
> haven''t found much more info.
This is something I struggled with for a little while on the first Rails 
app I built back with Rails pre-1.0 - it seemed like the path of least 
resistance has always involved treating each relationship add/edit as a 
separate event, updating the model immediately. However, what I really 
wanted to do was to have a form where you could edit the master record 
and some associated details at the one time, adding and deleting detail 
records as needed on the form, but only saving all changes back to the 
database when the user submitted.
In the end I managed to come up with a solution that works quite well 
for me - well enough that I haven''t really checked to see if there is a
better way of doing this with the current Rails release, so my solution 
may be able to be refined further... anyway, here is what I came up 
with:
View
On the view side in the form, you''ll have the master fields for your 
Contact object in the usual fashion, and then name the detail object 
fields for the number and contact after the association on the master 
object. Thus if Contact has_many :phone_numbers, I would name my detail 
object fields as phone_number[0][number], phone_number[0][category], 
phone_number[1][number], etc. In truth, the numbers don''t matter - they
only exist to uniquely identify each detail record within the form 
submission.
Adding/Deleting Detail Records
This can be done a couple of different ways - I''ve used both RJS 
rendering a partial with a session variable keeping track of the next 
number to use, and javascript in the browser to insert/delete detail 
records. I prefer the latter approach now, but it requires writing 
javascript rather than using RJS to shield you from it.
Controller
Most of the difficulty was in the controller, since I needed a way to 
process all the edits in one create/update action, and I wanted a way to 
do this that could be re-used on different forms. I ended up writing a 
module to handle this logic in a generic fashion, and now just include 
it into my Application controller base class when the same need arises.
The module defines a single save method that takes a couple of 
parameters: the name of the param that defines the master object values 
(e.g. contact), and the name (or names) of the object(s) in the params 
hash that define the values for each instance of the detail class(es): 
phone_number in this example. (Note though that you can for example 
create multiple detail objects for several different associations at 
once if you need to - such as a contact with many phone numbers and many 
email addresses).
By convention, I require the param keys to be named after the 
association on the master object, so that I can use 
reflect_on_associations to find all the other info I need to 
create/update the detail objects. It''s then a matter of 
locating/updating or creating both the master and all the detail 
records, and keeping a track of any detail records that may need to be 
deleted if they are not also in the submitted params. All of this is 
done inside a transaction, so that if a validation error occurs on say a 
detail attribute, the whole save can be rolled back.
Anyway, that''s an explanation of how the code works - if you''d
like a
copy, I''d be happy to email it to you.
Cheers,
Adam
-- 
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---