user3224820
user3224820

Reputation: 211

Nested Resources - No Method Error

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

Answers (2)

San
San

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

Doug Steinberg
Doug Steinberg

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

Related Questions