I'm working on an app to book different types of tours. I have 3 tables - 1) reservations 2) tours 3) join table (reservations_tours). I'm trying to pass the tour id to reservations, but keep getting this error:
Couldn't find Tour without an ID
app/controllers/reservations_controller.rb:12:in `create'
Reservations controller:
class ReservationsController < ApplicationController
def index
end
def new
@reservation = Reservation.new
@tour = Tour.find(params[:tour_id])
end
def create
@tour = Tour.find(params[:tour_id])
@reservation = Reservation.new(reservation_params)
#@reservation.tour = @tour # associate @reservation with video
if @reservation.save
Stripe.api_key = ENV["STRIPE_SECRET_KEY"]
Stripe::Charge.create(
:amount => 9000, # amount in cents, again
:currency => "usd",
:card => params[:stripeToken] # Get the credit card details submitted by the form
)
flash[:success] = "Your reservation has been booked for #{@reservation.date} for #{@reservation.passengers} person(s). Please save this info."
redirect_to new_tour_path
else
render 'new'
end
end
private
def reservation_params
params.require(:reservation).permit(:date, :passengers)
end
end
Tours controller:
class ToursController < ApplicationController
def index
end
def new
@tour = Tour.new
end
def create
@tour = Tour.new(tours_params)
if @tour.save
flash[:success] = "Tour #{@tour.name} has been successfully added."
redirect_to new_tour_path
else
flash[:error] = "The tour #{@tour.name} was not successfully saved. Please try again"
render 'new'
end
end
def show
@tour = Tour.find_by(id: params[:id])
@reservation = Reservation.new
end
def edit
end
def update
end
private
def tours_params
params.require(:tour).permit(:name, :amount)
end
end
Reservations view (new)
= javascript_include_tag "https://js.stripe.com/v2/"
= javascript_include_tag 'payment'
:javascript
Stripe.setPublishableKey("#{ENV['STRIPE_PUBLISHABLE_KEY']}");
.container
.row
.col-md-9
%h2= @tour.name
.col-md-3
%p= @tour.amount
= bootstrap_form_for(@reservation, html: { class: 'form-horizontal', id: 'payment-form'}) do |f|
= f.alert_message 'Please fix the errors below:'
= f.text_field :date
= f.text_field :passengers
%fieldset.credit_card
%span.payment-errors
.control-group
= label_tag :card_number, 'Credit card number:', class: 'control-label'
.controls
= text_field_tag :card_number, nil, name: nil, class: 'span3', data: {stripe: 'number'}
.control-group
= label_tag :security_code, 'Security code:', class: 'control-label'
.controls
= text_field_tag :security_code, nil, name: nil, class: 'span3', data: {stripe: 'cvc'}
.control-group
= label_tag :exp_date, 'Expiration:', class: 'control-label'
.controls
= select_month(Date.today, {add_month_numbers: true}, class: 'span2', data: {stripe: 'exp-month'})
= select_year(Date.today.year, {start_year: Date.today.year, end_year: Date.today.year + 4}, class: 'span1', data: {stripe: 'exp-year'})
%fieldset.actions.control-group
.controls
= f.submit 'Sign up'
Reservation model:
class Reservation < ActiveRecord::Base
has_many :reservations_tours, foreign_key: 'reservation_id'
has_many :tours, through: :reservations_tours
end
Tour model
class Tour < ActiveRecord::Base
has_many :reservations_tours, foreign_key: 'tour_id'
has_many :reservations, through: :reservations_tours
end
Join table
class ReservationsTours < ActiveRecord::Base
belongs_to :reservation, foreign_key: 'reservation_id'
belongs_to :tour, foreign_key: 'tour_id'
end
Routes:
Rails.application.routes.draw do
resources :reservations, only: [:new, :create]
resources :tours
end