Re: Creating Many Models in One Form

Sure that will work, but it's when it comes to adding a new field based on that index, it gets me lost.

On the build method I used the following.

<%= render :partial => 'add_image_link', :locals => { :index => @property.property_images.size } %>

_add_image_link.rhtml
<div id="add_image_link">
  <%= link_to_remote 'Add Another Image', :loading => "$('add_image_link').hide", :url => { :action => 'add_image', :index => index } %>
</div>

add_image.rjs
page.insert_html :bottom, :property_images, :partial => 'image_fields',
                 :locals => { :property_image => @property_image, :index => params[:index] }

page.replace :add_image_link, :partial => 'add_image_link', :locals => { :index => (params[:index].to_i + 1) }


Just not sure how to get this working on this new way, as there is nothing to loop through and I can't use fields_for

Now I'm a bit lost, sorry :)

Edit

_image_fields.rhtml

<div id="property_image_<%= index %>">
<% fields_for "property_images[#{index}]", property_image do |f| %>
  <p>
    <%= f.file_field :uploaded_data %>
    <%= f.text_field :caption %>
    <%= link_to_remote 'remove', :url => { :action => 'remove_image', :index => index } %>
  </p>
<% end %>
</div>

Last edited by stevepsharpe (2007-04-06 19:03:44)

Re: Creating Many Models in One Form

Since you only have one entry record to start off with you can use index to 1:

<%= render :partial => 'add_image_link', :locals => { :index => 1 } %>

Everything will mostly work after that.

However, there's a problem. If there's a validation error it won't work the way you expect because it will go back to only 1 record again.

To solve this, you need to go back to thinking about having many property_images, even though you only have one to start off with. Since you don't have a parent model to reach through you'll have to make your own array of models:

def new # or whatever you like to name it
  @property_images = [PropertyImage.new]
end

def create
  @property_images = params[:property_images].each_value { |property_image| Property.new(property_image) }
  #...
end


Then wherever I did @project.tasks before you would do @property_images.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Many Models in One Form

Thanks for all you help, I finally got it working!

P.S Love the Railscasts btw...

Last edited by stevepsharpe (2007-04-06 20:22:49)

Re: Creating Many Models in One Form

This last problem from stevepsharpe is great, but I have trouble understand the full solution.  I would like to do "n" models in one form and let the user add as many models as needed.  One user may have need for one model.  Another user may have need for twenty models.  In this case, creating models on the fly makes more sense.  Is there an article on creating n models in one form?

Re: Creating Many Models in One Form

See this other tutorial on how to do that.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Many Models in One Form

Is there any reason why brackets are used for tasks[#index] or could I use any other character ?

# in projects/new.rhtml
<% @project.tasks.each_with_index do |task, index| %>
   <% fields_for "tasks[#{index}]", task do |f| %>
   <p><%= f.text_field :name %></p>
   <% end %>
<% end %>

Returns me id like

id="some_model[1]_volume"

Using brackets gives me XHTML invalid id's and makes the id's different from the ones I get when looping over existing record like in ...fields_for "tasks[]", which returns me

id="simulation_transactions_566_volume"

Is it possible just using an underscore "tasks_#index" ?

Re: Creating Many Models in One Form

boemitsu wrote:

Is there any reason why brackets are used for tasks[#index] or could I use any other character?

Rails automatically groups the parameter in a hash when it has [] in it. This is why you need to use the square brackets.

boemitsu wrote:

Using brackets gives me XHTML invalid id's and makes the id's different from the ones I get when looping over existing record like in ...fields_for "tasks[]", which returns me

Yeah, I wish fields_for automatically removed the brackets for the id tag (would be a good patch if someone wants to submit it), but unfortunately it doesn't. You can manually specify the ":id" option to fix this behavior.

<p><%= f.text_field :name, :id => "tasks_#{index}_name" %></p>

boemitsu wrote:

Is it possible just using an underscore "tasks_#index" ?

Well, you will lose the benefit of easily being able to loop through this subset of task parameters in the create action. You'll have to loop through all parameters and parse out the task ones.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Many Models in One Form

Thanks for clarifying, I forgot to check the name attribute which also gets modified...

ryanb wrote:

You can manually specify the ":id" option to fix this behavior.

<p><%= f.text_field :name, :id => "tasks_#{index}_name" %></p>

This already helps me.

Cheers,
Michael

Re: Creating Many Models in One Form

ryanb wrote:

Sorry, I don't have a blog. All articles I have written are on this forum. Maybe some day I'll make my own site though.

What a fantastic glimpse into the future! wink

Re: Creating Many Models in One Form

I've been following this tutorial.  Great stuff.  Now, I am getting the following error on my index page:

"undefined method `quizanswer' for Quizquestion:Class"

also relevant is the location:

"#{RAILS_ROOT}/app/controllers/quiz_controller.rb:10:in `list'
#{RAILS_ROOT}/app/controllers/quiz_controller.rb:4:in `index'"

Here is my code from the quiz_controller:

  def index
    list
    render :action => 'list'
  end
 
  def list
    @quizquestion = Quizquestion.find(:all)
    @quizanswer = Quizquestion.quizanswer.find(:all)
  end
 
  def new
    @quizquestion = Quizquestion.new
    5.times { @quizquestion.quizanswers.build }
  end
 
  def create
    @quizquestion = Quizquestion.new(params[:quizquestion])
    params[:quizanswers].each_value do |quizanswer|
      @quizquestion.quizanswers.build(quizanswer) unless quizanswer.values.all?(&:blank?) 
    end
    if @quizquestion.save
      redirect_to :action => 'index'
    else
      render :action => 'new'
    end
  end
end

ummmmm....... now what?

Last edited by ravvuinn (2007-07-17 18:06:02)

Re: Creating Many Models in One Form

I have a problem based on this thread that need help with. It really got me pulling my hair out. Rather than posting this problem here, I started a new thread at this address:

http://railsforum.com/viewtopic.php?pid=32755#p32755

The problem is I have code based on this thread, multi-models per one form, etc. It works beautifully on my development machine, however, when I deployed, this code doesn't work anymore.

Re: Creating Many Models in One Form

Is there a way to create multiple models through the child?

For example I want to create an order, that belongs to an organization (which also has deadlines and other things), and I'd like to create them at the same time and I want to use the order model because it ties together all the other attributes and models.

The posted tutorials seem to only allow for the creation of multiple models if you use the parent model's new action.

Re: Creating Many Models in One Form

Do you mean create only the tasks and not the parent project model? Yes, that's possible. It takes just a only changes. You would just put the tasks in a @tasks instance variable and not build them through @project. It should work.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Many Models in One Form

I don't think that's what I'm talking about.

Let's say that instead of task belongs_to :project, project belongs_to :task.  Is it still possible to create and update both projects and tasks using  projects/new.rhtml as defined in projects_controller.rb?

Or does this have to be done in tasks/new.rhtml and tasks_controller.rb?

Does that make sense?

Re: Creating Many Models in One Form

We'll I've been able to create the parent model (has_many) from the new action of the child model (belongs_to) using the Agile book.

I'll keep the same convention as the example. So project :has_many tasks and tasks belong_to :project.

Let's this is the task_controller.rb

  def create
    @task = Task.new(params[:order])
    @project = Project.new(params[:project])
   
    Task.transaction do
      @task.project = @project
      @task.save!
      @project.save!
      redirect_to :action => :list
    end
  end

and then the form (task/new.rhmtl) looks like this:
<% form_tag :action => 'create' do %>

    <% fields_for :project do |project| %>
        Project Name: <%= project.text_field :name %>
    <% end %>

    <p><label for="task_name">Task Name:</label><br/>
    <%= text_field 'task', 'name'  %></p>

<%= submit_tag "Create" %>
<% end %>


Yea! But now my only problem is editing both of these at the same time through task/edit.rhtml.

None of the other tutorials or examples seem to work in my particular situation.

Last edited by chapman (2007-08-30 09:16:40)

Re: Creating Many Models in One Form

chapman wrote:

Yea! But now my only problem is editing both of these at the same time through task/edit.rhtml.

Since this tutorial only covers the creation process, I recommend making a separate thread for this problem and state specifically what isn't working.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Many Models in One Form

I thought that the conductor pattern might be a good addition to the information in this thread: http://blog.new-bamboo.co.uk/2007/8/31/ … s-on-rails

Last edited by jed.hurt (2007-08-31 23:16:37)

I thought about how mothers feed their babies with tiny little spoons and forks, so I wondered what do Chinese mothers use. Toothpicks?

Re: Creating Many Models in One Form

I would like to allow the user to add any number of "people" to an existing "household" --- from the show action of the household.

I am attempting to use the partials from Ryan's tutorial on adding any number of associated models when a new parent model is created. That works fine. Looking for help with adding associated records after the parent record is created.

Here is my code (which doesn't work):

 
households/show.rhtml
<%= render :partial => "add_person_link", :locals => { :index => 1} %>

    <% form_tag :action => 'add_people', :household_id => @household do %>
         <%= render :partial => 'person_fields', :locals => { :index => 1 } %>
    <%= submit_tag "Add to Household" %>
    <% end %>

households/_person_fields.rhtml
<div id="person_<%= index %>">
<% fields_for "people[#{index}]", person do |f| %>

<table border="0" cellspacing="1" cellpadding="1">

    <tr>
        <td>First Name: </td>
        <td><%= f.text_field :first_name %></td>
        <td>Last Name: </td>
        <td><%= f.text_field :last_name %></td>
    </tr>
...more fields...
</table>
   <p>
     <%= link_to_remote 'remove', :url => { :action => 'remove_person', :index => index } %>
   </p>
<% end %>
</div>


The error I get is
`@people[1]' is not allowed as an instance variable name

Thanks alot for any help.

39

Re: Creating Many Models in One Form

I need some help for a variation of this.Basically I have an model User.User can invite multiple  friends. How can an existing User invite multiple friends (create new records every time) . When I am using the techniques that are described here, it is filling up the existing records of the friends of the user.I do not want that behaviour. Every time a User wanted to invite new friends even if they are there in the database, I basically want to send them an invitation notice. Please help me.

@user = user.find(...)
@selected_friends.size.times {@user.user_friends.build}

<% @user.user_friends.each_with_index do |user_friend, index| %>
<% fields_for "user_friends[#{index}]", user_friend do |f| %>
<%= f.text_field :email , "size" => 23%>
<% end %>
<% end %>

Re: Creating Many Models in One Form

hi there.. i have some problem.. im a newbie in rails but i have to do my final year project.
can u edit my code here. i cant save the students mark into the gradebook table.

def egradebook
@class1s = Class1.find(:all)
@subjects = Subject.find(:all)
end

def addgrade
@gradebook = Gradebook.new
@students = Student.find(:all, :conditions => ["class1_id = ?", params[:class_1][:id]])
@teachers = Teacher.find(:all)
end

def creategrade
@gradebook.class1_id = params[:class_1][:id]
@gradebook.subject_id = params[:subject][:id]
@students = Student.find(:all, :conditions => ["class1_id = ?", params[:class_1][:id]])
@gradebook = Gradebook.new(params[:gradebook])
@teacher = Teacher.find(params[:id])
##here is the problem. unsure to add students mark and make the output as multiple of rows in gradebook table.
if @gradebook.save
    flash[:notice] = 'Gradebook Successfully Added.'
    redirect_to :action => 'index'
    else
     flash[:notice] = 'Please Login to Add Grade'
      render :action => 'login'
      end
end

hope u can help me asap. thank you.