Topic: Multiple child models in a dynamic form

update July 14, 2009: If you want to validate your child models using "validates_presence_of :parent" this won't work for new records in vanilla Rails 2.3.3, since the parent hasn't been created yet at the time of saving the children. You can circumvent this with the following plugin: http://github.com/h-lame/parental_control/tree/master

disclaimer: This tutorial builds on earlier tutorials by Ryan Bates and others found on this forum and around the net. If you see some stuff of yours in here and want to be credited you'll have to let me know!

also: This is the first tutorial I've written. I'm going to try to be as inclusive as possible and take everything very slowly but there's no guarantee of.. well anything tongue If you spot any mistakes or a cleaner/better way to handle any part please post a reply for everyone's benefit. wink So that out of the way let's get started!

requirements: You'll need Rails version 2.3 at least. The fields_for helpers do exist in earlier versions of Rails but will not function the way they do here. You will also need to include the Prototype javascript libraries. You can do this by adding the following code in the <head> section of your layout:

# app/views/layouts/application.html.erb (or your own layout file)
<html>
  <head>
    <title>My projects</title>
    <%= javascript_include_tag :defaults %>
  </head>
# ... etc

---

In Rails 2.3 the multi-model form helpers such as fields_for have become a lot more powerful, so let's see how we can use them to make Ryan's already excellent tutorials even cleaner!

First let's generate some models to work with. We'll go with the old example of a Project that has_many Tasks. We'll give the Project a title and a due_date and each task a name.

script/generate scaffold project title:string due_date:datetime
script/generate model task name:string project_id:integer

rake db:migrate


Right that's our database sorted, let's have a look at our models. First we set up the relationships
# app/models/project.rb
class Project < ActiveRecord::Base
  has_many :tasks, :dependent => :destroy
  # This is new!
  accepts_nested_attributes_for :tasks, :allow_destroy => true
end

# app/models/task.rb
class Task < ActiveRecord::Base
  belongs_to :project
end


Easy enough. The scaffold generator has already set up the basic views do we can go straight to adding tasks to the project form. First let's split the form from new.html.erb into a partial, which we'll put in /app/views/projects/_form.html.haml and let's add the child tasks as well:

# Our edited new.html.erb
<h1>New project</h1>

<% form_for(@project) do |f| %>
  <%= render :partial => 'form', :object => f -%>
<% end %>

# And _form.html.erb
<%= form.error_messages %>
<p>
  <%= form.label :title %><br />
  <%= form.text_field :title %>
</p>
<p>
  <%= form.label :due_date %><br />
  <%= form.datetime_select :due_date %>
</p>
<div id="tasks">
  <h3>Tasks</h3>
  <% form.fields_for :tasks do |task_form| -%>
    <%= render :partial => 'task', :locals => { :form => task_form } %>
  <% end -%>
</div>
<p>
  <%= form.submit 'Save' %>
</p>


As you can see fields_for is now a method called on the Project's form builder object. Because we defined :tasks as being a nested model in the Projects model above fields_for will render its block once for every child Task found in our Project.

Of course we still need to add the Task partial, for now let's keep it simple:

<div class="task">
  <p>
    <%= form.label :name %>
    <%= form.text_field :name, :size => 15 %>
  </p>
</div>

So with all the views sorted let's set up our new action to pre-populate our project with 2 empty tasks:
# app/controllers/projects_controller.rb
def new
  @project = Project.new
  2.times { @project.tasks.build }
end

Now you're ready for the first test. Start mongrel (or whatever server you're using) and navigate to /projects/new. You should see the Project form as well as 2 Task entries at the bottom.

In fact the form is already operational! The addition of "accepts_nested_attributes" in the project model handles all the rough details of converting the Tasks attributes and checking whether they are new or existing records. Amazing! And if you change your edit.html.erb to use the partial like new.html.erb you'll be able to edit project and tasks as well.

Of course we're stuck with 2 tasks now, so let's start making the form dynamic by adding an "add task" link.

I prefer to keep these in a helper, so go ahead and open app/helpers/projects.rb and add the following method (be careful this won't work properly yet!):

module ProjectsHelper
  def add_task_link(form_builder)
    link_to_function 'add a task' do |page|
      form_builder.fields_for :tasks, Task.new do |f|
        page.insert_html :bottom, :tasks, :partial => 'task', :locals => { :form => f }
      end
    end
  end
end

Here comes the tricky part! Adding a single extra record works perfectly but when we add a second it breaks. Why is this? Let's take a look at the rendered html, before we add new tasks:
<div id="tasks">
  <h3>Tasks</h3>
  <input id="project_tasks_attributes_0_id" name="project[tasks_attributes][0][id]" type="hidden" value="1" />
  <div class="task">
    <p>
      <label for="project_tasks_attributes_0_name">Name</label>
      <input id="project_tasks_attributes_0_name" name="project[tasks_attributes][0][name]"  size="15" type="text" value="task 1" />
    </p>
  </div>

  <input id="project_tasks_attributes_1_id" name="project[tasks_attributes][1][id]" type="hidden" value="2" />
  <div class="task">
    <p>
      <label for="project_tasks_attributes_1_name">Name</label>
      <input id="project_tasks_attributes_1_name" name="project[tasks_attributes][1][name]" size="15" type="text" value="task 2" />
    </p>
  </div>
</div>


On closer inspection it looks like fields_for gives every task a serial number by the form helper. Our first record has number 0, the next one number 1, and so on. Because the add_task_link helper we created renders the partial when the page is generated it uses the next available index (2 in our case) for each subsequent time we click on "new task". So when you click it twice both new tasks end up with index 2, this obviously won't fly.

Unfortunately there's no standard Rails way of dealing with this (as far as I'm aware at least), so we'll have to rig something up to make the ids unique. Javascript is our only option because this has to happen client-side.

First we'll add the :child_index option to fields_for, this will let us set the generated index to a string of our choosing. Then we'll use javascript to give it a more or less random id, based on the current date.

Because we have to modify the html as it's inserted into the #tasks div, we'll have to jury rig the content to insert. Sadly that means we can't use the page.insert_html helper rails provides any more.

module ProjectsHelper
  def add_task_link(form_builder)
    link_to_function 'add a task' do |page|
      form_builder.fields_for :tasks, Task.new, :child_index => 'NEW_RECORD' do |f|
        html = render(:partial => 'task', :locals => { :form => f })
        page << "$('tasks').insert({ bottom: '#{escape_javascript(html)}'.replace(/NEW_RECORD/g, new Date().getTime()) });"
      end
    end
  end
end

Quite a mouthful but actually not that complicated when we look at it closely. All we're doing is inserting the new form fields at the bottom of the #tasks div and replacing all strings "NEW_RECORD" with a unique number, the number of miliseconds since epoch. This ensures we won't accidentally make two records with the same id unless somsone manages to add two tasks in less than a milisecond wink

Now we simply add the new add_task_link to the form view, under the tasks div:

# app/views/projects/_form.html.erb
<div id="tasks">
  <h3>Tasks</h3>
  <% form.fields_for :tasks do |task_form| -%>
    <%= render :partial => 'task', :locals => { :form => task_form } %>
  <% end -%>
</div>
<%= add_task_link(form) %>

Hard to believe but that's the most difficult part done! We can now add new projects with an unlimited number of tasks. We can even edit existing projects and add tasks with impunity!

In all the excitement we could be forgiven for overlooking the final step but we can not delete tasks yet! Thankfully here again fields_for and accept_nested_attributes make our life much easier. Lets add another helper method to the projects_helper:

  # Display the remove link for a child form
  def remove_task_link(form_builder)
    if form_builder.object.new_record?
      # If the task is a new record, we can just remove the div from the dom
      link_to_function("remove", "$(this).up('.task').remove();");
    else
      # However if it's a "real" record it has to be deleted from the database,
      # for this reason the new fields_for, accept_nested_attributes helpers give us _delete,
      # a virtual attribute that tells rails to delete the child record.
      form_builder.hidden_field(:_delete) +
      link_to_function("remove", "$(this).up('.task').hide(); $(this).previous().value = '1'")
    end
  end

As you can see all we're doing is either dropping the new div if the Task is a new record. If the Task is already saved to the database all we have to do is add a hidden "_delete" field which indicates the task is to be dropped. To make our view a little prettier we make the _delete field invisible and set it through javascript. If you prefer less javascript you could also use a simple check_box.

The only thing remaining is to add the delete link to the view:

# app/views/projects/_task.html.erb
<div class="task">
  <p>
    <%= form.label :name %>
    <%= form.text_field :name, :size => 15 %>
    <%= remove_task_link( form ) %>
  </p>
</div>

And that's all! You now have a complex, javascript driven, form that will let you save a project with any number of child tasks all in one go.

Once the tasks are added you can show them in your show view the same way you would with any related objects. Here's a quick example (thanks for reminding me to add this tallp wink)

# app/views/projects/show.html.erb
<h2>Tasks</h2>
<ul>
<% for task in @project.tasks %>
  <li>
    <%=h task.name %>
  </li>
<% end %>
</ul>

Addition:
I've seen many questions about forms with child objects two levels deep (maybe a Task has_many Contributors) but this is far more complicated. As you saw in the rendered html above, adding a task to a project is as simple as making the field names "project[task_attributes][0][name]". A contributor's fields would look like this: "project[task_attributes][0][contributor_attributes[0][name]".

This doesn't look too complicated until you start adding tasks and contributors by javascript. Not only do you have the trivial task of making a random id for your contributor but you have to somehow determine from the DOM the parent task's id. Currently I have no good ideas on how to do this without terribly ugly hacky code.

Last edited by marsvin (2009-07-14 18:11:05)

Re: Multiple child models in a dynamic form

Nice write up smile

Re: Multiple child models in a dynamic form

Thank you for this tutorial. Couldn't get it to work, tho. There appears to be a missing closing paren for JS replace.

Re: Multiple child models in a dynamic form

morbusg wrote:

Thank you for this tutorial. Couldn't get it to work, tho. There appears to be a missing closing paren for JS replace.

Thanks for that, good eye! wink Now fixed!

Re: Multiple child models in a dynamic form

Great tutorial! I have been looking for something like this for days!

One thing that I can't quite make work id the add_task_link. When the view is rendered that function doesn't output anything. Where and how exactly do I use it?

Boo.

Re: Multiple child models in a dynamic form

All right, got it to work by moving the link_to_function inline. For some reason the helper function call doesn't return all the JS.
This is so awesome! :-D

EDIT: nevermind, the helper function call works just fine. Not sure what was wrong.

Last edited by morbusg (2009-03-21 05:25:44)

Re: Multiple child models in a dynamic form

s.cannon wrote:

One thing that I can't quite make work id the add_task_link. When the view is rendered that function doesn't output anything. Where and how exactly do I use it?

Oh you're right I skipped where to put it. I've updated the tutorial to fix this but short answer I usually put it under the tasks div. Although in theory you could put it anywhere you like.

# app/views/projects/_form.html.erb
<%= form.error_messages %>
<p>
  <%= form.label :title %><br />
  <%= form.text_field :title %>
</p>
<p>
  <%= form.label :due_date %><br />
  <%= form.datetime_select :due_date %>
</p>
<div id="tasks">
  <h3>Tasks</h3>
  <% form.fields_for :tasks do |task_form| -%>
    <%= render :partial => 'task', :locals => { :form => task_form } %>
  <% end -%>
</div>
<%= add_task_link(form) %> # <=== right here!
<p>
  <%= form.submit 'Save' %>
</p>

Last edited by marsvin (2009-03-21 20:18:47)

Re: Multiple child models in a dynamic form

Hi,


Excellent tutorial. Thank you.

I could not get the "add a task" link working. Kept getting "ReferenceError: $ is not defined". The code looked good to me.

Well, I feel foolish. I never included javascript anywhere. So I added in views/layouts/projects.html.erb after the <%= stylesheet_link_tag 'scaffold' %> line:

  <%= javascript_include_tag "prototype" %>
  <%= javascript_include_tag :defaults %>

Done. It worked. Hurrah!

Thank you again for the explanations and putting this tutorial together. I love Ryan's screencasts but for a newbie they never do the trick since I would like a working example from start to finish. I am not sure why he does not do this since using scaffolding takes seconds. I am sure I will be able to consume the screencasts more easily as I progress.

Cheers

Re: Multiple child models in a dynamic form

Ah excellent, thanks! Some of these things seem so natural I forgot not everyone will know to include the prototype libraries. I added the requirement to the top.

And yeah, I myself had a little trouble with Ryan's tutorials early on but as you learn to digest the API (also something that can look a little daunting at first) and get the scaffolding and the basic MVC model under control things definitely start coming more naturally. My guess is Ryan's current Railscasts are aimed more at the intermediate crowd as there are so many places to look for basic Rails tutorials these days already.

Re: Multiple child models in a dynamic form

Marsvin, Congratulations on your first tutorial.
I haven't made use of it yet but multi model forms are definitely on my agneda for the near future and I will certainly be paying carefull attention to this tutorial when it comes to the time to do this.

I had also been wondering how exactly Rails 2.3 was going to handle this.
I had problems with Ryans rails casts and check boxes as did many others when I had a little experimentation a few months ago.
I'll also be lloking to making the Javascript gracefully degrading when the time comes and if I manage this I'll let you know.

Thank you

James

What you want and what you need are too often not the same thing!
When your head is hurting from trying to solve a problem, stop standing on it. When you are the right way up you will see the problem differently and you just might find the solution.
(Quote by me 15th July 2009)

Re: Multiple child models in a dynamic form

Sounds good. To my shame I have yet to apply proper degrading links to most of my apps, so it'd be good to see someone else's experiences with this!

Re: Multiple child models in a dynamic form

Marsvin. Thanks for the tutorial.

I was wondering if there is a way to 'populate' the new task fields with predefined values (each new task with a different value). For example when I access my bank account through my bank's web page I want to pay some of my accounts (clothing accounts, electricity and phone bills etc.) a payments page is loaded with all my vendor details already listed, each with an empty 'amount' field next to it. All I have to do is fill in the amounts that I want to pay each vendor and click the "pay" button.

This feature is very user friendly and saves one from having to type in or select names from a list for each vendor. Tell me this is possible!

In another context. If I were a math teacher with lets say 20 students in my class. I have student, test and score models. I would want to create a new test scores for  all of my 20 students in one submit.

class Student
has_many :scores
has_many :tests, :through => :scores
end

class Score
belongs_to :student
belongs_to :test
end

class Test
has_many :scores
has_many :students, :through => :scores
end


How do I create a new test form that will allow me to create a test and each student's test scores all at once? The form should automatically list all students without having to go through the motion of doing a collection select for each one individually as it is described elsewhere by Stephen Chu
http://www.stephenchu.com/2008/03/param … ls-in.html

Thanks

Archie

Last edited by archie (2009-04-04 14:09:26)

Re: Multiple child models in a dynamic form

Thanks to the way ActiveRecord works that's very easy. In fact you're already pretty close to what you need. In this case you should add the "accepts_nested_attributes_for" to your Test model:

class Test < AR::Base
  has_many :scores
  has_many :students, :through => :scores
  accepts_nested_attributes_for :scores, :allow_destroy => true
end

If we want to pre-populate the new test view with students the main difference is that we'll have to set the student_id to the scores. So let's just loop through each of the students and add a score to the test for each of them:
class TestController < ApplicationController
  def new
    @test = Test.new
    Student.all.each do |student|
      @test.scores.build( :student_id => student.id )
    end
  end
end

Now if you arrange your view in the same way as in the tutorial (renaming Project to Test and Task to Score) you should get a pre-populated form.

edit: Just to make sure it's clear, you'll also have to add a hidden_field (or something) to the score form partial to make sure the student_id is sent to the create action. So something like this:

<div class="score">
  <p>
    <%= form.hidden_field :student_id %>
    <%= form.label :value %>
    <%= form.text_field :value, :size => 5 %>
  </p>
</div>

Last edited by marsvin (2009-04-04 18:15:52)

Re: Multiple child models in a dynamic form

Thanks for the feedback.  I will try it out and let you know how it goes.
Cheers
Archie

Re: Multiple child models in a dynamic form

Marsvin

I'm glad to report that it works great. Thanks a stack. I was having trouble displaying the student' name next to the value in the New form. The only way I got it to work was to use the select method as follows:

<%= form.select :student_id, Student.all.collect {|s| [s.name, s.id]} %>

However, although it correctly displays the student's name before the value it is displayed in a drop-down box. This is not ideal as it allows the user to play around with the selection. Do you have any suggestion on how to display the name without the drop-down box?

Your help is much appreciated.
Thanks

Archie

Re: Multiple child models in a dynamic form

Well one alternative would be to use radio buttons, although with a lot of students that could make for a very messy view.

If I were you I probably wouldn't make the student selectable at all. You're pre-populating the Test with all your Students in advance anyway, why not just render their name and pass the id as a hidden field? Or is that what you meant?

<div class="score">
  <p>
    <%= form.hidden_field :student_id %>
    <%= form.object.name %>
    <%= form.label :value %>
    <%= form.text_field :value, :size => 5 %>
  </p>
</div>

(form.object takes the object that the form was generated from, in this case the Student)

Re: Multiple child models in a dynamic form

Hi All,
I am unsing rails 2.1 .
In my application i have ctreated multiple models in one sigle form.And working fine.But i have implemented the application with dyanamically adding a task with the help of ryans complexforms2 post.Here i am getting the problems.

I have models called:
containerformat
trransportstream
program
stream

add the ossocoations between models like:
containerformat has_many transportstreams
transportstream has_many programs and belongs_to containerformats
programs has_many streams and belongs_to transportstreams
videocodecs hasmany streams
audiocodecs hasmany streams
streams belongs to containerformats,transportstreams,programs,videocodecs,audiocodecs

in containerformatcontroller:
new method:
-----------
def new
        @containerformat = Containerformat.new
    @containerformat.transportstreams.build(params[:transportstream])
    @transportstream = Transportstream.new
    @program = Program.new
    @stream = Stream.new
    @containertypes = Containertype.find(:all)
    @videocodecs = Videocodec.find(:all)
    @audiocodecs = Audiocodec.find(:all)
        respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @containerformat }
    end
  end

create method:
----------------
def create
    @containerformat = Containerformat.new(params[:containerformat])
    @transportstream = @containerformat.transportstreams.build(params[:transportstream])
    @program = @transportstream.programs.build(params[:program])
    @stream = @program.streams.build(params[:stream])
    respond_to do |format|
    if @containerformat.upload(params[:containerformat])
    @containerformat.location = params[:containerformat][:location].original_filename
    @containerformat.streamName = File.basename(@containerformat.location)
    @containerformat.location = '//172.24.191.68/data'
        @containerformat.location=File.join(@containerformat.location,@containerformat.streamName)
         
      if @containerformat.save and @transportstream.save  and @program.save and @stream.save
        flash[:notice] = 'Containerformat was successfully created.'
        format.html { redirect_to(@containerformat) }
        format.xml  { render :xml => @containerformat, :status => :created, :location => @containerformat }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @containerformat.errors, :status => :unprocessable_entity }
      end
    end
    end
  end

in containerformat views:
new.html.erb
------------
i am using fields_for to create the other model fields in one form.

ex:
<div id="content">
<h1>New containerformat</h1>

<% form_for(@containerformat, :url=>{:action => 'create'}, :html => {:multipart => "true"}) do |f| %>
  <%= f.error_messages %>
<table>
  <p>
     <%= f.hidden_field :streamName %>
  </p>
  <p>
    <%= f.label :Location %><br />
    <%= f.file_field :location %>
  </p>
 
  <p>
      <%= f.label :ContainerFmt %><br />
      <%= f.text_field :containerFmt %>
  </p>
</table>
 
  <%fields_for @transportstream  do |f|%>
     <h1>Stream Details</h1>
     <table> 
         <tr>
         <td><%= f.label :numPrograms%></td>
         <td><%= f.label :encryptionstd %><br /></td>
         </td>
         </tr>
         <tr>
           <td><%= f.text_field :numPrograms%></td>
           <td><%= f.text_field :encryptionstd %></td>
           <p><%= f.hidden_field :containerformat_id %></p>
         </tr>
     </table>
<% end %>
    ...
here i have added other model fields...   
  <p>
 
    <%= f.submit "Create" %>
  </p>
<% end %>
<%= link_to 'Back', containerformats_path %>

-----
with the above code i am able to upload data into different models.

Now i am trying to implement application like add_task given by ryanpost.
Here i am able to get the add_task and remove_task links and are working fine.But problem here is whatever the  task i added, once i click on create button it is not saving in database with all fields which are all defind in add_task partial.

my code snippet for this implementation:
in new.html.erb
--------------
i added this code
<div id="streams">
      <%= render :partial => 'stream', :collection => @program.streams %>
    </div>
     <p><%= add_stream_link "Add a stream" %></p>
           
_stream.html.erb partial:
-----------------------
<div class="stream">
<% fields_for "program[stream_attributes][]", stream do |ts_form| %>
  <h1>Audio and Video Details</h1>
                   <table>
                 <tr>
                   <td>Video Codec</td>                   
                   <td>Audio Codec</td>
                   
                   </tr>
                <tr>
               
                   <td><%= collection_select(:stream, :videoCodec_id, @videocodecs, :id, :name) %></td                   <td><%= collection_select(:stream, :audioCodec_id, @audiocodecs, :id, :name) %</td>
                  </tr>
                </table>
                   
                    <table>
                 <tr>
                   
                    <td>Resolution</td>
                    <td>Audio SamplingRate</td>
                           
                            </tr>
                <tr>
                <td><%= ts_form.text_field :resolution %></td>           
                   <td><%= ts_form.text_field :audioSamplingRate %></td>
                   </tr>
                        </table>
                       
               <table>         
             <tr>
               
               <td>Aspect Ratio</td>
               <td>NoOfChannels</td>
             </tr>
             <tr>
               
               <td>
                 <%= ts_form.text_field :aspectRatio %>
               </td>
               <td>
                         <%= ts_form.text_field :noChannel %>
                       </td>
       
             </tr>           
                       
                  </table>
                     
         <%= link_to_function "remove", "$(this).up('.stream').remove()" %>
            <% end %>
     
</div>

and in my model containerformat:
-------------------------------

i have method for stream attributes
def stream_attributes=(stream_attributes)
  stream_attributes.each do |attributes|
    streams.build(attributes)
  end
end

in containerformat_helper.rb
----------------------------
def add_stream_link(name)
  link_to_function name do |page|
    page.insert_html :bottom, :streams, :partial => 'stream', :object =>  Stream.new
  end
end

-------
thas all about my code modifications to add tasks dynamically.

And once i try to add tasks dynamically here i am getting error like:

NoMethodError in Containerformats#show
Showing app/views/containerformats/show.html.erb where line #58 raised:

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.name

Extracted source (around line #58):

55: <tr id="content-odd">
56: <tr  style="background-color: #CCFFCC;">
57:             <th width="200" align="left">videoCodec</th>
58:             <td> <%=h @stream.videocodec.name %>    </td>
59:             </tr>
60:             
61: <tr id="content-even">

from this what i understand is the error is pointing to show page.
i  could not able to find where is the problem in show page.Because in show page just i am printig all parameres from different models.And i can see the attributes are saved in to the databse except videocodec_id and audiocodec_id is not saving.
and if i dont go for add task then i m not getting any error.

Can any one suggest me where i am doing the mistake.
Help me out to resolve this problem.

thanks
Srikanth

Re: Multiple child models in a dynamic form

Hi Marsvin

Yes that's what I meant.  I tried to use

<%= form.object.name %>

but it gave me  and "undefined method `name' for #<Score:0x33a79d0>" so I can't seem to pull the student name in from the student model unless I use the select(or collection_select) method described before.  I am going to keep on trying but I would appreciate any other suggestions from anyone.

Thanks
Archie

Re: Multiple child models in a dynamic form

Update: Problem solved.

<div class="score">
   <p>
     <%= form.hidden_field :student_id %>
     <%= form.object.student.name %>
     <%= form.label :value %>
     <%= form.text_field :value, :size => 3 %>
   </p>
</div>

#on line 4 inserted student between object. and name


Again thanks for all your help.

Cheers
Archie

Re: Multiple child models in a dynamic form

srikanth wrote:

from this what i understand is the error is pointing to show page.
i  could not able to find where is the problem in show page.Because in show page just i am printig all parameres from different models.And i can see the attributes are saved in to the databse except videocodec_id and audiocodec_id is not saving.
and if i dont go for add task then i m not getting any error.

The error is reported in the show view but it actually happens before then. Like you said, the videocodec_id is not being saved to the database. That probably means that the program[:stream_attributes] aren't being processed properly. Can you show the development.log from when you submit the form?

edit:

Come to think of it, this is probably it:

<td><%= collection_select(:stream, :videoCodec_id, @videocodecs, :id, :name) %></td>

Since you're not using the form builder (ts_form) it doesn't use the fields_for logic. You end up with a select box named just "stream" rather than "containerformat[stream]". You're probably better off using plain select here, something like this:
<td><%= ts_form.select :videoCodec_id, @videocodecs.collect{ |v| [v.id, v.name] } %></td>

Last edited by marsvin (2009-04-09 22:48:58)