Ruby on rails 为属于不同模型的模型创建独立表单?

Ruby on rails 为属于不同模型的模型创建独立表单?,ruby-on-rails,forms,Ruby On Rails,Forms,所以我有两种型号的房间和预订 Room对象是由拥有该房间的人预先创建的,并存储在数据库中 我想允许不同的用户稍后创建属于该特定房间的预订(在不同的页面和完全不同的表单上),这样当我想为该房间列出预订列表时,我只需执行类似于@room.reservations的操作 我希望在RoomsController中创建房间,并在ReservationsController中创建预订 class ReservationsController < ApplicationController #

所以我有两种型号的
房间
预订

Room
对象是由拥有该房间的人预先创建的,并存储在数据库中

我想允许不同的用户稍后创建属于该特定房间的预订(在不同的页面和完全不同的表单上),这样当我想为该房间列出预订列表时,我只需执行类似于
@room.reservations
的操作

我希望在
RoomsController
中创建房间,并在
ReservationsController
中创建预订

class ReservationsController < ApplicationController
    # What I want to do:
    @listing = Listing.new(params[:id])   # no way of getting Listing's id
    @reservation = @listing.reservations.build(reservation_params)

    # etc...
不幸的是,我似乎不知道如何用“Rails方式”来实现这一点。我想到的最好的办法是:

# .../rooms/new
= form_for @room, room_path do |f|
    # Form that creates a room

# .../reservations/new
= form_for @reservation, reservation_path do |f|
    # Form that creates a reservation
但是当我这样做时,我没有办法(至少我知道)引用
ReservationsController
中的特定的列表

class ReservationsController < ApplicationController
    # What I want to do:
    @listing = Listing.new(params[:id])   # no way of getting Listing's id
    @reservation = @listing.reservations.build(reservation_params)

    # etc...
这根本不是我想要的。我希望能够使用我的
预订控制器

class ReservationsController < ApplicationController
    # What I want to do:
    @listing = Listing.new(params[:id])   # no way of getting Listing's id
    @reservation = @listing.reservations.build(reservation_params)

    # etc...
如何实现这一点?

使用嵌套路由:

resources :rooms, shallow: true do
  resources :reservations
end
这嵌套了房间上下文中预订的“收集路线”

              Prefix Verb   URI Pattern                                Controller#Action
   room_reservations GET    /rooms/:room_id/reservations(.:format)     reservations#index
                     POST   /rooms/:room_id/reservations(.:format)     reservations#create
new_room_reservation GET    /rooms/:room_id/reservations/new(.:format) reservations#new
    edit_reservation GET    /reservations/:id/edit(.:format)           reservations#edit
         reservation GET    /reservations/:id(.:format)                reservations#show
                     PATCH  /reservations/:id(.:format)                reservations#update
                     PUT    /reservations/:id(.:format)                reservations#update
                     DELETE /reservations/:id(.:format)                reservations#destroy
               rooms GET    /rooms(.:format)                           rooms#index
                     POST   /rooms(.:format)                           rooms#create
            new_room GET    /rooms/new(.:format)                       rooms#new
           edit_room GET    /rooms/:id/edit(.:format)                  rooms#edit
                room GET    /rooms/:id(.:format)                       rooms#show
                     PATCH  /rooms/:id(.:format)                       rooms#update
                     PUT    /rooms/:id(.:format)                       rooms#update
                     DELETE /rooms/:id(.:format)                       rooms#destroy
然后,您需要更改ReservationsController,以便在创建预订时使用
参数[:room\u id]
查找房间:

class ReservationsController < ApplicationController
  before_action :set_reservation, only: [:show, :edit, :update, :destroy]
  before_action :set_room, only: [:new, :create]

  # GET /rooms/:room_id/reservations
  def index
    @room = Room.includes(:reservations).find(params[:room_id])
    @reservations = @room.reservations.all
  end

  # GET /rooms/:room_id/reservations/new
  def new
    @reservation = @room.reservations.new
  end

  # POST /rooms/:room_id/reservations
  def create
    @reservation = @room.reservations.new(reservation_params)

    if @reservation.save
      redirect_to @reservation, notice: 'Reservation was successfully created.'
    else
      render :new
    end
  end

  # ... The rest of the controller actions

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_reservation
      @reservation = Reservation.find(params[:id])
    end

    def set_room
      @room.find(params[:room_id])
    end

    # Only allow a trusted parameter "white list" through.
    def reservation_params
      params.require(:reservation).permit(:room_id, :starts_at, :ends_at)
    end
end

没有必要在表单中包含房间id,因为我们是从请求url获取的。

注意,我使用的是
room
,因为您不太清楚
列表
在应用程序中的含义。尽管如此,同样的原则仍然适用。哦,对不起,我的意思是“房间”而不是“挂牌”!我将尝试一下,看看它对我的效果如何,但只要看看它,我就知道这可能是我的正确答案。这是我用来生成答案代码的演示Rails应用程序: