Re: Creating Variable Number of Models in One Form

The problem still remains? That's strange. Make sure the changes are fully saved. This also might be a caching issue so try restarting the web server.

If this does not solve the problem, try placing this line at the top of the new.rhtml view:

<%= debug(@voucher.positions) %>

This should spit out information on the positions so you can see if they are being created.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

We're getting closer. The debug information is:

- !ruby/object:Position
  attributes:
    name:
    voucher_id:
    account:
    debit_credit:
    category_id:
    amount: !ruby/object:BigDecimal 0.0
  new_record: true

And believe it or not with this line the position is visible, without it's not. Seems to be a initializing problem? I'm sure that is easy to solve but I don't know how? Sorry for annoying you with such rudimental questions but at this time rails has some kind of magic for me. It will getting better in a few weeks, I promise! wink

Last edited by BigTitus (2007-02-07 05:05:40)

Re: Creating Variable Number of Models in One Form

So it's working properly when you call this debug method? That is, the fields are correctly displayed? Are all 10 fields displayed?

Try this in the controller and see if it has the same behavior as the debug line..

def new
  @voucher = Voucher.new
  10.times {@voucher.positions.build}
  @voucher.positions.to_yaml
end

That last line is basically doing with the debug line is, but the output goes into never-never land. Try it without that debug call and with and without the above line to see if it changes the behavior of the application. It really shouldn't. But if it does, it sounds like a bug.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

Well ... it does. What kind of bug do you mean? Within the rails environment? Or within my application?

And by the way, I can't find 'to_yaml' in rails API, am I blind?

Re: Creating Variable Number of Models in One Form

to_yaml is an undocumented goodie (don't you love those?). It basically exports the object to YAML format, but this should not have any effect on the app. I know Rails 1.2 changed how the models are loaded. Are you using 1.2?

Lastly, remove the to_yaml line and see if this fixes it: (add to_a)

  <div id="positions">
    <% @voucher.positions.to_a.each_with_index do |position, index| %>
      <%= render :partial => 'position', :locals => { :position => position, :index => index } %>
    <% end %>
  </div>

If my hunch is correct, this will fix the problem and it is a bug in Rails 1.2 - unless you are overriding the "positions" method in Voucher or something? Please post the Voucher model if you think it contains something which may be interfering with this.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

to_a works for me, but I am using Rails 1.1.6. Even the voucher model does not look very special:

class Voucher < ActiveRecord::Base
  has_many :positions
   
  validates_presence_of :date, :desc, :voucher_nr
  validates_uniqueness_of :voucher_nr
   
  protected
  def validate
    errors.add(:voucher_nr, "should be at least 1" ) if voucher_nr.nil? || voucher_nr <= 1
  end
end

Don't know, if we will unravel this mystery but the main thing is the problem seems to be fixed now.

Thank you very much for that! smile

Re: Creating Variable Number of Models in One Form

To post #18,19,20, I just had a quick question!  This forum has been extremely useful in our rails application development btw!

I'm running into the same problems that darrenemo had regarding the 'update' action when having the tasks be duplicated and not updated appropriately. 

Basically, what's the easiest way to allow a user to 'add' tasks dynamically while editing/removing tasks all on the same page.  So that the 'update' action handles all of this (the build new, edit existing, and delete those that were requested to be deleted)

Has there been an updated tutorial posted?

Thanks again!!

Last edited by perugina (2007-03-06 12:20:38)

Re: Creating Variable Number of Models in One Form

perugina wrote:

Has there been an updated tutorial posted?

Not yet. I'm still planning on writing one but haven't gotten around to it yet. I need to do some testing to find the best way to do this. It can get rather complex.

The only thing I can suggest for now is to keep the new tasks and the existing tasks completely separate on the edit page. Even make two delete actions for deleting an existing task vs. one that is new. After you are done doing this you will no doubt have a lot of duplication, but you will be in a better position to refactor and remove the duplication (merge the two delete actions into one, etc.).

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

ryanb wrote:

The only thing I can suggest for now is to keep the new tasks and the existing tasks completely separate on the edit page. Even make two delete actions for deleting an existing task vs. one that is new. After you are done doing this you will no doubt have a lot of duplication, but you will be in a better position to refactor and remove the duplication (merge the two delete actions into one, etc.).

Thanks!  That's the path I've started to take, I just wanted to see if there was a better place that I should start from!  I'll let you know how it goes and post my results if they're clean enough!  smile

Last edited by perugina (2007-03-06 13:07:45)

Re: Creating Variable Number of Models in One Form

I'd be interested in seeing that as well ...

Re: Creating Variable Number of Models in One Form

Ryan, this is a great article. I made a small error in my equivalent of the partial _task_fields.rhtml that prevented me from removing the task fields from the remove link.

The error was calling using <div id="task_#{index}index %>"> in stead of <div id="task_<%= index %>">. I gave me two popups but I fixed it now.

The strange thing is that I can't remove the first task. Since each task is displayed by the same partial and remove link, this should also work.

Re: Creating Variable Number of Models in One Form

I fixed the problem after reading this post:

http://kekova.ca/articles/2006/04/15/ie … e_tr_error

I had to place my id="tasks" in the <tbody> element and I moved the id="task_<%= index %>" attribute to the <tr> element of my partial. This way I could add and delete a row for a task dynamically!

But in the end: great tutorial Ryan!

Re: Creating Variable Number of Models in One Form

Cool, glad you got it working.

I'm using divs instead of a table in the tutorial, but I guess if you have a table it would need to be a little different. Interesting.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

Thank you very much for this tutorial! It has been extremely helpful.
I have only run into one problem so far. The user is able to click the Add Task link multiple times before it is updated with a new index. This results in multiple sets of fields with the same index.

I was able to remedy this by hiding the link with javascript. I just added this bit of code to the link_to_remote call:

:loading => "document.getElementById(\"div_containing_link\").style.display = 'none'"

Is there a better way to prevent this from happening?

Re: Creating Variable Number of Models in One Form

You can use prototype to shorten it up:

:loading => "$('div_containing_link').hide"

I think that's the best way to do it besides going without ajax. Good catch.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

I'm having some trouble with adding another Phone Number field.  The remove feature works fine.

Here is my form code:

<table>
  <tbody id="phone_numbers">
    <% @company.phone_numbers.each_with_index do |phone_number, index| %>
    <%= render :partial => 'phone_number_fields', :locals => { :phone_number => phone_number, :index => index } %>
    <% end %>
  </tbody>
  <%= render :partial => 'add_phone_number_link', :locals => { :index => @company.phone_numbers.size } %>
</table>

And here is my phone number field partial:

<% fields_for "phone_numbers[#{index}]", phone_number do |f| %>
    <tr id="phone_number_<%= index %>">
        <td><%= f.text_field :number  %></td>
        <th>
            <!-- Insert Location here -->
        </th>
        <td class="addremove">
        <%= link_to_remote 'remove', :url => { :action => 'remove_phone_number', :index => index } %>
    </td>
    </tr>
<% end %>

And here is my add_phone_number.rjs contents:

page.insert_html :bottom, :phone_numbers, :partial => 'phone_number_fields', 
  :locals => { :phone_number => @phone_number, :index => params[:index] }
 
page.replace :add_phone_number_link, :partial => 'add_phone_number_link',
  :locals => { :index => (params[:index].to_i + 1) }

Whenever I click on the "Add another phone number" link, nothing happens.

Any advice?  Also, is there anyway to debug what happens when I click on the "Add another phone number" link.

Last edited by drlelon (2007-05-06 13:49:26)

Re: Creating Variable Number of Models in One Form

Check out your development.log file, this will tell you if any request is being sent when you click the "add phone number" link.

Also, can you post your add_phone_number_link partial?

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

The add_phone_number_link partial is :

<tr id="add_company_phone_number">
    <td class="add">
        <%= link_to_remote 'Add another', :url => { :action => 'add_phone_number', :index => index } %>
    </td>
    <th>&nbsp;</th>
    <td class="addremove"></td>
</tr>

Re: Creating Variable Number of Models in One Form

What does your development.log say when you click the link?

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Variable Number of Models in One Form

development.log says:

Processing PeopleController#add_phone_number (for 127.0.0.1 at 2007-05-06 17:21:59) [POST]
  Session ID: BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%0ASGFzaHsABjoKQHVzZWR7AA%3D%3D--14208aa5d41b3f187781bbb656ee449ed5e96234
  Parameters: {"action"=>"add_phone_number", "controller"=>"people", "index"=>"2"}
Rendering people/add_phone_number


ActionView::TemplateError (`@phone_numbers[2]' is not allowed as an instance variable name) on line #3 of app/views/people/_phone_number_fields.rhtml:
1: <% fields_for "phone_numbers[#{index}]", phone_number do |f| %>
2:      <tr id="phone_number_<%= index %>">
3:              <td><%= f.text_field :number  %></td>
4:              <th>
5:                      <!-- Insert Location here -->
6:              </th>