While reading about creating forms in Rails, I came across Nested Forms. On the first glance it looked difficult, but as I progressed, I said to myself, “It’s not so bad!”.
In order to create Nested Forms, it is important to understand about the helpers provided by Rails.
1). accepts_nested_attributes_for: Imagine that we have a BookShelf which has many Books. And the Books contain a title and an author. This setup calls for nested attributes.
  class BookShelf < ActiveRecord::Base
    has_many :books
    accepts_nested_attributes_for :books
  end
accepts_nested_attributes_for provides us with books_attributes= (setter) method. Now, we can set the attributes of model books, through bookshelf hash. The params in this case will be.
params = {
  bookshelf: {
    size: "small",
    books_attributes: [
      {title: "Coders at Work", author: "Peter Seibel"},
      {title: "Design Patterns in Ruby", author: "Russ Olsen"},
      {title: "The Pragmatic Programmer", author: "Andy Hunt"}
    ]
  }
}
accepts_nested_attributes_for also provides us with some options:
- 
    
reject_if: Helps us to ignore the hashes that fail the criteria or required validations.class BookShelf < ActiveRecord::Base has_many :books accepts_nested_attributes_for :books, reject_if: proc { |attribute| attribute['title'].blank? } end - 
    
allow_destroy: Allows us to delete the records trough attributes hash.class BookShelf < ActiveRecord::Base has_many :books accepts_nested_attributes_for :books, allow_destroy: true end 
2). fields_for: This helper takes two arguments. The first argument is the model for which we want to create the attributes and the second is the object. It allows the methods to be called on builder in order to generate fields.
 
 
 
  <%= f.fields_for :books, Book.new do |book_attributes| %>
    <%= book_attributes.text_field :title %>
    <%= book_attributes.text_field :author %>
  <% end %>
 Using these form helpers, we can create nested forms.
Step1. Add accepts_nested_attributes_for in the model whose hash will contain the nested attributes.
    class BookShelf < ActiveRecord::Base
      has_many :books
      accepts_nested_attributes_for :books
    end
As stated above, this code will provide us with books_attributes= method.
Step2. Update strong parameters in BookShelf controller so that it accepts the books_attributes.
    class BookShelvesController < ApplicationController
      def index
        @bookshelves = BookShelf.all
      end
      def show
        @bookshelf = BookShelf.find(params[:id])
      end
      def new
        @bookshelf = BookShelf.new
      end
      def create
        @bookshelf = BookShelf.new(bookshelf_params)
        if @bookshelf.save
          redirect_to bookshelf_path(@bookshelf)
        else
          render new_bookshelf_path
        end
      end
      private
      def bookshelf_params
        params.require(:bookshelf).permit(:size, books_attributes: [:title, :author])
      end
    end
Step 3. Updating the view. In our view, we use fields_for helper method.
    <div>
      <%= form_for :bookshelf do |f| %>
        <div>
          <%= f.label :size %>
          <%= f.text_field :size %>
        <div/>
        <div>
          <%= f.fields_for :books, Book.new do |book_attributes| %>
            <%= book_attributes.label :title %>
            <%= book_attributes.text_field :title %>
            <br/>
            <%= book_attributes.label :author %>
            <%= book_attributes.text_field :author %>
          <% end %>
        <div/>
        <%= f.submit %>
      <% end %>
    <div/>
Finally, login to rails server and check the form.