Home > Enterprise >  Get id of intance Ruby on Rails
Get id of intance Ruby on Rails

Time:10-19

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).

  • Related