Reputation: 211
I'm creating a ticket booking app as my sample project using Ruby on Rails 4.1. Three are three models - Events, Tickets and Bookings. Events have many tickets and bookings. Tickets have many bookings and they belong to events. Bookings belongs to events and tickets.
The routes file looks like:
Rails.application.routes.draw do
resources :charges
root 'events#index'
resources :events do
resources :tickets
resources :bookings
end
end
The buttons to the new booking page are located in my events/show page which has the following code:
<% @event.tickets.each do |ticket| %>
<div class="row">
<div class="col-md-8">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= ticket.ticket_name %></td>
<td><%= ticket.ticket_price %></td>
<td><%= ticket.ticket_quantity %></td>
<td><%= link_to "Buy Now", new_event_booking_path(@event, ticket), class: "btn btn-primary" %></td>
<td><%= link_to "Edit", edit_event_ticket_path(@event, ticket), class: "btn btn-link" %></td>
<td><%= link_to "Delete", event_ticket_path(@event, ticket), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-link" %></td>
</tr>
</table>
</div>
</div>
As you can see, the event and ticket variables are grabbed when the user clicks the "Buy Now" button. However, when I use the following code in my Bookings controller:
class BookingsController < ApplicationController
def new
@event = Event.find(params[:event_id])
@ticket = @event.tickets.find(params[:id])
@booking = Booking.new
end
def create
@event = Event.find(params[:event_id])
@ticket = @event.tickets.find(params[:id])
@booking = @event.bookings.create(booking_params)
if @booking.save
redirect_to [@event, @booking]
else
render 'new'
end
end
def show
@event = Event.find(params[:event_id])
@booking = @event.bookings.find(params[:id])
end
private
def booking_params
params.require(:booking).permit(:buyer_name, :email, :mobile, :address, :order_quantity)
end
end
I get the ActiveRecord::RecordNotFound in BookingsController#new. Couldn't find Ticket without an ID error.
The new page looks like this (pretty barebones as I testing the functionality)
<%= form_for ([@event, @booking]) do |f| %>
<div class="row">
<div class="form-group">
<%= f.label :buyer_name %>
<%= f.text_field :buyer_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :order_quantity %>
<%= f.text_field :order_quantity, class: "form-control" %>
</div>
</div>
<%= f.submit "Pay now", class: "btn btn-primary" %>
The Events Model:
has_many :tickets, dependent: :destroy
has_many :bookings
has_many :charges
The Tickets model:
belongs_to :event
has_many :bookings
The Bookings model:
belongs_to :event
belongs_to :ticket
has_many :charges
The foreign key association looks like this:
add_reference :bookings, :ticket, index: true
How to solve this error?
Upvotes: 0
Views: 275
Reputation: 1954
You can not add ticket to the new_event_booking_path
, the way you have done. Instead, do it this way:
new_event_booking_path(@event, ticket_id: ticket.id)
Note that we are adding an additional parameter called ticket_id
to the path. This is because route for event_booking_path
does not know anything about ticket.
Then, in your controller, find the ticket like this:
@ticket = @event.tickets.find(params[:ticket_id])
Update
In your form, add a hidden field for ticket_id
like this:
<%= hidden_field_tag :ticket_id, @ticket.id.to_s %>
Upvotes: 1
Reputation: 1162
You need to take @ticket out of new
and create
@ticket = @event.tickets.find(params[:id])
There is no params[:id]
being passed in from the Buy Now link
Take that line out of new
and create
actions and your error should go away
Upvotes: 0