【问题标题】:how to add id of another model in the controller on active record association in ruby on rails如何在 ruby​​ on rails 的活动记录关联的控制器中添加另一个模型的 id
【发布时间】:2020-09-08 15:08:10
【问题描述】:

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

这是 schema.rb

    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", precision: 6, null: false
        t.index ["hotels_id"], name: "index_bookings_on_hotels_id"
        t.index ["user_id"], name: "index_bookings_on_user_id"
      end

这是创建预订表格的链接

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

booking_controller.rb

def create
    @booking = Booking.new(booking_params)
    @booking.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

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

【问题讨论】:

    标签: ruby-on-rails ruby activerecord associations


    【解决方案1】:

    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| %>
    

    【讨论】:

      【解决方案2】:

      我相信你有如下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
      

      【讨论】:

      • 这是一种方法,但绝对不是 Rails 方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多