在 Rails 上获取实例 Ruby 的 ID

Get id of intance Ruby on Rails

我正在构建一个 ruby 应用程序来预订住宿。所以我想在预订模型的显示操作中放置一个 form_with。 Model Booking 是 User 模型和 Logement 模型之间的连接。要进行预订,需要 user_id 和 logement_id,这样我才能获得 user_id 的价值,而不是 logement_id。我尝试在 ApplicationController 中创建 helper_method 但它不起作用。我的终端结果是:“ActiveRecord::RecordNotFound(无法找到没有 ID 的 Logement)” 我怎样才能获得 logement_id 来进行预订?提前致谢

应用程序控制器

class ApplicationController < ActionController::Base

    helper_method :set_logement_id, :get_logement_id 

    def get_logement_id
        @logement_id = params[:id]
    end
        
    def set_logement_id
        @id = @logement_id
    end
end

页面控制器

class PagesController < ApplicationController
    def home
    end

    def create   
    end

    def show
        get_logement_id
        @logement = Logement.find(params[:id])
        @booking = Booking.new
    end

    def search
        @city = params[:city]
        $depart = params[:depart]
        $arrive = params[:arrive]
        @voyageurs = params[:voyageurs]
        @logements_disponible = Logement.where(["city = ? and start_date_of_availability <= ? and end_date_of_availability >= ? and voyageur >= ?",@city, $arrive, $depart, @voyageurs])
    end
end

预订控制器

class BookingsController < ApplicationController
    before_action :set_booking, only: [:show, :edit, :update, :destroy]

    def index
        @bookings = Booking.all
    end

    def new
        @booking = Booking.new
    end

    def show
    end

    def create
        @booking = Booking.new(booking_params)
         @booking.logement = Logement.find(set_logement_id)
        @booking.user = current_user
        if @booking.save
            redirect_to booking_path(@booking) 
        else
            render "new"
        end
    end

    def edit
    end

    def update
        if @booking.update(booking_params)
            redirect_to booking_path(@booking)
        else
            render :new
        end
    end

    def destroy
        @booking.destroy
        redirect_to root_path
    end

    private

    def booking_params
        params.require(:booking).permit(:start_booking, :end_booking)
    end

    def set_booking
        @booking = Booking.find(params[:id])
    end
end

show.html.erb

<h1>Show <%= @logement.title %> Id du logement:  <%= @logement.id %></h1>

    <%= @logement.title %>
    <%= @logement.adresse %>
    <%= @logement.zipcode %>
    <%= @logement.city %>
    <%= @logement.latitude %>
    <%= @logement.longitude %>
    <%= @logement.voyageur %>
    <%= @logement.start_date_of_availability.try(:strftime, ("%e %B %Y")) %>
    <%= @logement.end_date_of_availability.try(:strftime, ("%e %B %Y")) %>

    <% @logement.images.each do |photo| %>
        <%= image_tag photo.url %>
    <% end %>

<br>
<br>

<!-- link to new reservation-->
<h1>Booking</h1>

<%= form_with(model: @booking) do |form| %>
    <%= form.label :start_booking %>
    <%= form.date_field :start_booking %>

    <%= form.label :end_booking %>
    <%= form.date_field :end_booking %>

    <%= form.submit "Reserver" %>
<% end %>

<%= link_to "reserver", new_booking_path %>

Booking.rb

class Booking < ApplicationRecord
  belongs_to :logement
  belongs_to :user
end

User.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # , :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :validatable, :confirmable
          
  has_many :bookings
  has_many :logements, dependent: :destroy
  
end

Logement.rb

class Logement < ApplicationRecord
    mount_uploaders :images, ImageUploader
    serialize :images
    geocoded_by :address
    after_validation :geocode, if: :address_changed?

    def address
        [adresse, city, zipcode].compact.join(", ")
    end

    def address_changed?
        adresse_changed? | city_changed? | zipcode_changed?
    end

    belongs_to :user
    has_many :bookings
end

routes.rb

Rails.application.routes.draw do
  
  devise_for :users, controllers: {
    registrations: 'users/registrations'
  }
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root to: "pages#home"

  resources :logements
  resources :users#, only: [:index, :show]
  resources :bookings
  resources :pages, only: [ :show]

  get "search", to: "pages#search"
  post "pages/:id", to: 'pages#show'

end

航站楼

Started POST "/bookings" for ::1 at 2021-10-18 08:48:11 +0200
Processing by BookingsController#create as JS
  Parameters: {"authenticity_token"=>"[FILTERED]", "booking"=>{"start_booking"=>"2021-10-06", "end_booking"=>"2021-10-23"}, "commit"=>"Reserver"}
Completed 404 Not Found in 4ms (ActiveRecord: 0.0ms | Allocations: 1105)


  
ActiveRecord::RecordNotFound (Couldn't find Logement without an ID):
  
app/controllers/bookings_controller.rb:17:in `create'

只需将隐藏的 logement_id 字段放在 form_with 中并从 @logement 设置它,而不使用 helper method(set_logement_id).

这失败了,因为 set_logement_id returns 这个:@logement_id = params[:id]。 但是在您的请求中没有名为 id 的参数。

有多种修复方法。您可以重组您的路线或将 logement_id 作为参数传递给您的表单,如下所示:

<%= form.hidden_field :logement_id, value: @logement_id %>

并将 BookingsController 中的第 17 行替换为:

@booking.logement = Logement.find(params[:logement_id))