2015-07-20 89 views
1

所以,我有兩個型號RoomReservation爲屬於不同模型的模型創建獨立表單?

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形式的隱藏字段,但我沒有辦法驗證它。我測試了通過填寫表格,然後改變所述隱藏的輸入字段的PARAMS [:ID]在Chrome的值檢查元素,這當然將其發佈到不同的室,這是不期望的。

我現在堅持這樣做:

# 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

我該如何認識到這一點?

回答

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 

因爲我們從請求url中獲取它,所以沒有必要在表單中包含房間ID。

+0

請注意,我用'Room',既然你是不是真正清楚'Listing'意味着你的應用程序。儘管如此,同樣的原則也適用。 – max

+0

對不起,我的意思是「房間」,而不是「上市」!我要給這個提示一下,看看它是如何實現的,但只要看看它,我已經可以告訴我這對我來說可能是正確的答案。 –

+0

這是我用來爲答案生成代碼的演示Rails應用程序:https:// github。COM/maxcal /沙箱/樹/ 31526836 – max