Creating multiple records for a model in a single view in Rails

10,755

Solution 1

The reason you can't use the same method as the other question in your post is bc @book is not a nested attribute of user. You are only creating a form for one new book, so without anything special in the controller, rails will only save one book. One option is to make books a nested attribute of user so that you can create multiple books at once. Here is how you need to set up your models and form to handle nested attributes.

Class User < ActiveRecord::Base
  has_many :books
  accepts_nested_attributes_for :books, :reject_if => lambda { |b| b[:title].blank? }
  attr_accessible :books_attributes
end 

Class Book < ActiveRecord::Base
  belongs_to :user
end

The reject_if will ignore any records that are submitted to the controller without a title. You will want this since you are assuming that many users won't use all 10 fields. Below is your form.

<%= form_for @user do |f| %>
  <%= f.fields_for :books, [Book.new]*10 do |book| %>
    <%= book.text_field :title %>
    <%= book.association :book_category %>
  <% end %>
  <%= f.submit %>
<% end %>

It is important to note that this form will be submitted to the Users controller since it is a user form. The users controller will handle creating/updating all the books like it would any other attribute of user since books are now accepted as a nested attribute. For more examples checkout this Railscast on nested attributes.

As I mentioned above, this is only one option. If you do not want to make book a nested attribute of user then another option is to generate your 10 sets of book input fields like you are already doing and then break apart the params hash in the create action in the Books controller. By doing this you could loop through the hash and create a book for each set of inputs. This is much more "hacky" than using accepts_nested_attributes_for but it is another option so I figured I would mention it.

Solution 2

The example article you referenced was talking about nested model forms. Railscasts also has a video here: http://railscasts.com/episodes/196-nested-model-form-part-1

Both refer to a single instance of a model with relationships to other models.

What you want to do is multiple instances of the same model, not a nested relationship.

My question is, why? Do they really save time tabbing from one fieldset to another over hitting enter to submit a single record?

If you want to save time in data entry why not just have the create action redirect back to new so they can instantly enter the next record? Or use AJAX to add a new fieldset to the page after each record is submitted?

I think these methods will keep your view and controller nice and RESTful.

Share:
10,755
yellowreign
Author by

yellowreign

Updated on June 13, 2022

Comments

  • yellowreign
    yellowreign almost 2 years

    I have a model named Book, and I want to adjust the standard Book#new to show the fields for 10 books, so that 10 can be created at once instead of just one.

    I looked at this question and found that I could repeat the form if I added 10.times to my form. However, I didn't do it correctly because a new record is saved, but with all fields null.

    What I want to do is to:

    1. Allow the user to enter up to 10 books at one-time and then save them
    2. If the user populates only three book records, create only three (and ignore the seven records in the form others with null values)

    My view:

    <%= simple_form_for(@book) do |f| %>
      <%= f.error_notification %>
      <% 10.times do |index|%>
        <%= f.input :title %>
        <%= f.association :book_category %>   
      <% end %>
    
      <%= f.submit %>
    <% end %>
    

    My controller is unchanged from the scaffolding code:

    def new
      @book = Book.new
    end
    
    def create
      @book = Book.new(params[:book])
    end