# Nested forms with multiple models

**URL:** <https://www.ruby-forum.com/t/nested-forms-with-multiple-models/153122>\
**Category:** Rails\
**Created:** [November 12, 2008, 1:32pm UTC](https://www.ruby-forum.com/t/nested-forms-with-multiple-models/153122 "2008-11-12T13:32:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@alex](https://www.ruby-forum.com/u/alex)\
**Post date:** [November 12, 2008, 1:32pm UTC](https://www.ruby-forum.com/t/nested-forms-with-multiple-models/153122/1 "2008-11-12T13:32:31Z")

</div>

Hey guys, I need your help again!

I have a form in which I want to nest multiple models. Kind of like “a  
project has many tasks” but rather “a flight has one flight time per  
flight type”.

So it’s three models - Flight, FlightType and FlightTime. Flight →   
FlightTime ← FlightType

What I want to do is to loop through the FlightTypes in the add/edit  
Flight form, and present a text box whose value then will be stored  
as :hours in a FlightTime along with a :flight\_id and :flight\_type\_id  
value. I hope I’ve made myself clear.

This is the code I have in my flight\_form view currently:

[http://pastie.org/312947](http://pastie.org/312947)

Now this works perfectly when _adding_ FlightTimes as I’m using a  
FlightTime.new, but the issue I have is that I also want to be able to  
edit the values. When I try to use this form for editing, all the  
values in the boxes are emptied and anything I put in them are added  
as new FlightTimes (obviously). There can only be one FlightTime per  
FlightType per Flight, so to speak.

So, anyone up for the task to help me out?

Thanks,  
Alex

---

<div class="post-metadata">

**Author:** ![alex](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@alex](https://www.ruby-forum.com/u/alex)\
**Post date:** [November 12, 2008, 2:41pm UTC](https://www.ruby-forum.com/t/nested-forms-with-multiple-models/153122/2 "2008-11-12T14:41:01Z")

</div>

one suggestion: don’t put business logic in your views. replace  
“FlightTime.new” with “@flight\_time” and let your controller figure  
out if it should be a new or existing record.

---

<div class="post-metadata">

**Author:** ![alex](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@alex](https://www.ruby-forum.com/u/alex)\
**Post date:** [November 12, 2008, 4:06pm UTC](https://www.ruby-forum.com/t/nested-forms-with-multiple-models/153122/3 "2008-11-12T16:06:35Z")

</div>

On Nov 13, 12:40 am, jemminger [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> one suggestion: don’t put business logic in your views. replace  
> “FlightTime.new” with “@flight\_time” and let your controller figure  
> out if it should be a new or existing record.
> 
> On Nov 12, 7:32 am, Alex J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
> …
> 
> > Now this works perfectly when _adding_ FlightTimes as I’m using a  
> > FlightTime.new, but the issue I have is that I also want to be able to  
> > edit the values. When I try to use this form for editing, all the  
> > values in the boxes are emptied and anything I put in them are added  
> > as new FlightTimes (obviously). There can only be one FlightTime per  
> > FlightType per Flight, so to speak.

As per jemminger, if you want your action and template to both create  
new objects and edit existing ones you need to put this logic into the  
action in the controller.

So you might have:  
if params[:id]  
@foo=Foo.find(params[:id])  
else  
@foo=Foo.new  
end

In your view, you can then get rails to put whatever values are  
currently in @foo into your fields:  
form\_for :foo , :url … do |f|  
f.text\_field :field1  
…  
end

or:  
fields\_for :foo do |f|  
f.text\_field :field1  
…  
end

and rails will automagic in @foo.field1 as the value in that text  
field because you specified ‘:foo’.  
(Sorry, can’t get my head around your models)

I was thinking that if you have an array of objects eg foo has\_many  
bars and you want to edit all those bars, then in the view you could  
loop thru the array with an index eg:

@foo.bars.each\_with\_index do |bar,idx|  
fields\_for “bars[#{idx}]” , bar do |b|  
b.text\_field :field1  
…  
end  
…  
end

Which, on submission, will generate  
params[‘bars’][‘0’][‘field1’] =\>   
etc  
Not sure if that’s good but I think it works.  
You could skip the whole ‘with\_index’ thing if it’s just has\_one.

You’ll also need to embed id value for each record into a hidden field  
in your form if you’re editing an existing item so that you can find  
it and update it instead of creating a new object when the form is  
submitted.  
There are security implications here - people can post a random id  
instead - so you need to think that through carefully.

–  
Daniel B.
