如何在Ruby中的活动记录关联中的控制器中添加另一个模型的ID

问题描述

我必须建立一个酒店预订系统,所以我制定了一个用户,酒店和预订模型,并给出了所有必要的关联。在预订模型中,我给了用户和酒店:参考 因此,在booking_controller中的create方法中创建新的预订时,我给出了devise gem提供的@ booking.user = current_user。 我如何在控制器中提供hotel_id。

这是schema.rb

EXPLAIN

这是创建预订表格的链接

    create_table "bookings",force: :cascade do |t|
        t.integer "user_id",null: false
        t.string "guest_name"
        t.integer "no_of_guest"
        t.integer "room"
        t.date "check_in_date"
        t.date "check_out_date"
        t.integer "hotels_id",null: false
        t.datetime "created_at",precision: 6,null: false
        t.datetime "updated_at",null: false
        t.index ["hotels_id"],name: "index_bookings_on_hotels_id"
        t.index ["user_id"],name: "index_bookings_on_user_id"
      end

booking_controller.rb

<%= link_to 'Book Now',new_booking_path(:id => @hotel.id),:class => 'btn btn-success btn-sm' %>

我应如何以及在何处为预订设置特定的酒店ID?

解决方法

Rails实现此目的的方法是创建a nested route

resources :hotels do
  resources :bookings,shallow: true
end

这将创建路由GET /hotels/:hotel_id/bookings/newPOST /hotels/:hotel_id/bookings以及命名的辅助程序new_hotel_booking_path

<%= link_to 'Book Now',new_hotel_booking_path(@hotel),class: 'btn btn-success btn-sm' %>

调整控制器,以便您在回调中创建酒店并在酒店外建立预订:

class BookingsController < ApplicationController
  before_action :set_hotel,only: [:new,:index,:create]

  # GET /hotels/1/bookings/new
  def new
    @booking = @hotel.bookings.new
  end

  # POST /hotels/1/bookings
  def create
    @booking = @hotel.bookings.new(booking_params) do |b|
      b.user = current_user
    end
    respond_to do |format|
      if @booking.save
        format.html { redirect_to @booking,notice: 'Booking successful' }
        format.json { status: :created,location: @booking } # send either a Location header or a response entity - not both
      else
        format.html { render :new }
        format.json { render json: @booking.errors,status: :unprocessable_entity }
      end
    end
  end

  private

  def set_hotel
    @hotel = Hotel.find(params[:hotel_id])
  end 

  # ...
end

传递一个数组以使用以下形式创建嵌套资源:

# Rails < 5.1
<%= form_for([@hotel,@booking]) do |f| %>

# Rails 5.1+
<%= form_with(model: [@hotel,@booking]) do |f| %>
,

我相信您的booking模型如下:

class Booking
  belongs_to :user
  belongs_to :hotel
......
end

我假设您在页面中有一个hotel列表或有hotel个对象,并且在其前面有Book Now链接。在代码中,您已经传递了id作为参数,但是您应该传递hotel_id而不是id

<%= link_to 'Book Now',new_booking_path(hotel_id: @hotel.id),:class => 'btn btn-success btn-sm' %>

然后在booking_controller.rb中,您必须具有booking_params方法以及createnew方法。

def new
  @booking = Booking.new
  @booking.hotel = Hotel.find(params[:hotel_id])
end

def create
  @booking = Booking.new(booking_params.merge!(user: current_user))
  respond_to do |format|
      if @booking.save
        format.html { redirect_to @booking,notice: 'Booking successfully !!!' }
        format.json { render :show,status: :created,location: @booking }
      else
        format.html { render :new }
        format.json { render json: @booking.errors,status: :unprocessable_entity }
      end
  end
end

private
def booking_params
  params.require(:booking).permit(:user_id,:hotel_id,add_other_fields_you_want_to_save)
end

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...