首页 > 解决方案 > 获取实例 Ruby on Rails 的 id

问题描述

我正在构建一个 ruby​​ 应用程序来预订住宿。所以我会在模型 Booking 的显示操作中放置一个 form_with。模型预订是用户模型和登录模型之间的连接。要进行预订需要 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

显示.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 %>

预订.rb

class Booking < ApplicationRecord
  belongs_to :logement
  belongs_to :user
end

用户.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

日志.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

路线.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'

标签: ruby-on-railsrubyruby-on-rails-6model-associations

解决方案


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

有多种方法可以解决它。您可以重组您的路线或logement_id使用您的表单传递 as 参数,如下所示:

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

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

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

推荐阅读