I am trying to make a car park booking application and general booking works. When I type in user id
, spot id
and select is_booked
.
Now I would like the button next to the list of spots to work the same way, but I can't get the id of the spot, like this:
<% @spots.each do |spot| %>
<tr>
<td><%= spot.name %></td>
<td><%= link_to 'Show', spot %></td>
<td><%= link_to 'Edit', edit_spot_path(spot) %></td>
<td><%= link_to 'Booking', new_booking_path %></td>
</tr>
<% end %>
</tbody>
The path at the moment is to new_booking but only for preview,eventually it will be create_booking.
I've tried several ways but none works, I am able to reference all ids but not a single id. This one is sample from booking_controller to new_booking definition and I give these parameters:
@booking = current_user.bookings.build(:spot_id => Spot.ids, :is_booked => true)
I hope I've described the problem clearly. I'm fairly new to ruby and this seems to be a trivial error that I don't know how to fix. please help. I attach the link to github - https://github.com/ppablo1609/parkingapplication
CodePudding user response:
One approach is to nest the resource in your /config/routes.rb file.
so that relationship will look like this:
resources :spots do
resources :bookings
end
After doing that, if you run rails routes from the command line you will now see a new route new_spot_booking_path
, and you can use it in your template as new_spot_booking_path(spot).
Take a look at https://guides.rubyonrails.org/routing.html#nested-resources and routing in general
Good luck!
CodePudding user response:
The Rails way to solve this is by creating a nested route:
resources :spots do
resources :bookings, shallow: true
end
This will create the path /spots/:spot_id/bookings
which means that the spot id is passed as part of the URL.
class BookingsController < ApplicationRecord
before_action :set_spot, only: [:new, :create, :index]
before_action :set_booking, only: [:show, :edit, :update, :destroy]
# GET /spots/1/bookings/new
def new
@booking = @spot.bookings.new
end
# POST /spots/1/bookings/new
def create
@booking = @spot.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 was successfully created." }
format.json { render :show, status: :created, location: @booking }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @booking.errors, status: :unprocessable_entity }
end
end
end
private
def set_spot
@spot = Spot.find(params[:spot_id])
end
def set_booking
@booking = Booking.find(params[:id])
end
def booking_params
params.require(:booking)
.permit(:starts_at)
end
end
# app/views/bookings/new.html.erb
<%= render partial: 'form' %>
# app/views/bookings/_form.html.erb
<%= form_with(model: [@spot, @booking]) |form| %>
# ...
<%= form.submit %>
<% end %>