Search code examples
ruby-on-railsformsnested-formsrails-models

Form which creates a quantity of another model with form field


I have two models, Hotel and Room. I want to create a form that will allow me to add a new hotel and rooms, which indicates the name of the hotel and the quantity of rooms. I know I should use "nested form", but it is hard for me to implement it properly.

Here is my code:

HotelsController

class HotelsController < ApplicationController

  def index
    @hotels = Hotel.all
  end

  def new
    @hotel = Hotel.new
  end

  def create
    @hotel = Hotel.new(hotel_params)

    if @hotel.save
      redirect_to @hotel
    else
      render 'new'
    end           
  end

  def show
    @hotel = Hotel.find(params[:id])
  end

  def destroy
    @hotel = Hotel.find(params[:id])
    @hotel.destroy
    redirect_to hotels_url, notice: 'Hotel was successfully destroyed.'
  end

  private

  def hotel_params
    params.require(:hotel).permit(:name, :rooms_count)
  end
end

Hotel model

class Hotel < ApplicationRecord
  has_many :rooms, dependent: :destroy
  accepts_nested_attributes_for :rooms
end

Room model

class Room < ApplicationRecord
    belongs_to :hotel, optional: true # avoiding rails 5.2 belongs_to error 
end

form

<%= form_with scope: :hotel, url: hotels_path, local: true do |form| %>
  <p>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </p>

  <p>
    <%= form.label :rooms_count %><br>
    <%= form.number_field :rooms_count %>
  </p>

  <p>
    <% form.fields_for :rooms  do |f|%>
      <p>
        **THE CODE**
      </p>
    <% end %>
  </p>

  <p>
    <%= form.submit %>
  </p>
<% end %>

Solution

  • I have found a solution to my question.

      def create
        @hotel = Hotel.new(hotel_params)
        @hotel.rooms_count.times do 
          @hotel.rooms.build
        end
    
        if @hotel.save
          redirect_to @hotel
        else
          render 'new'
        end           
      end
    

    It implement a @hotel.rooms.build as many times as @hotel.rooms_count number entered in Rooms Count field in form.