I am building an ruby app to book accommodations. So I would to put a form_with in the show action for the model Booking. Model Booking is a connection between is User model and Logement Model. To do a Booking a need user_id and logement_id, so I can get the valeur of user_id but not to logement_id. I try to make a helper_method in ApplicationController but its doesn't work. My Terminal resuls is : "ActiveRecord::RecordNotFound (Couldn't find Logement without an ID)" How can I get logement_id to make a booking instance? Thanks in advance
AppplicationController
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
PagesController
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
BookingsController
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
Terminal
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'
CodePudding user response:
This fails because the set_logement_id
returns this: @logement_id = params[:id]
.
But in your request isn't a parameter called id.
There are multiple ways how to fix it. You could restructure your routes or passing the the logement_id
as parameter with your form like this:
<%= form.hidden_field :logement_id, value: @logement_id %>
and replacing your line 17 in your BookingsController with this:
@booking.logement = Logement.find(params[:logement_id))
CodePudding user response:
Just place hidden logement_id
field inside form_with
and setup it from @logement
, without this helper method(set_logement_id)
.