Forum: Ruby on Rails Nested forms with multiple models

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D4cf9def06882f717033e0ef4181a270?d=identicon&s=25 Alex Jonsson (alexnder)
on 2008-11-12 13:32
(Received via mailing list)
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

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
D69d23d8e811e8ab2a8593380d6ede63?d=identicon&s=25 Jeff Emminger (jemminger)
on 2008-11-12 14:41
(Received via mailing list)
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.
9b4c04c050122bcea16a6f3376d680fa?d=identicon&s=25 Daniel Bush (danb)
on 2008-11-12 16:06
(Received via mailing list)
On Nov 13, 12:40 am, jemminger <jemmin...@gmail.com> 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 Jonsson <alex.e.jons...@gmail.com> 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'] => <some-value>
  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 Bush
This topic is locked and can not be replied to.