所以我有两个模型Room
和Reservation
。
Room
对象事先由拥有房间并存储在数据库中的人创建。
我想让其他用户稍后在 belongs_to 那个特定的房间创建预订(在不同的页面和完全独立的表单上),这样当我想拉出一个列表时对于那个房间的预订,我可以简单地做@room.reservations
之类的事情。
我希望在RoomsController
中创建房间,并在ReservationsController
中创建预订。
不幸的是,我似乎无法弄清楚如何使用" 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...
我认为我可以将其作为隐藏字段添加到reservations
表单中,但我没有办法验证它。我通过填写表单然后在Chrome的Inspect Element中更改隐藏的输入字段的params [:id]值来测试它,当然这会将其发布到不同的房间,这是不可取的。
我现在不知道这样做了:
# I ended up having to create a "reserve" action in the listings controller
= form_for @listing, :url => { :controller => "listings", :action => "reserve" } do |f|
f.fields_for :reservation do |r|
# All the fields to create a reservation here...
这根本不是我想要的。我希望能够使用我的ReservationsController
。
我如何实现这一点?
答案 0 :(得分:1)
使用嵌套路线:
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以在创建预订时使用params[:room_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
您需要稍微更改表单,以便发布到/rooms/:room_id/
:
= form_for([@room, @reservation]) do |f|
# ... fields go here
由于我们从请求网址获取房间ID,因此无需在表单中包含房间ID。