我正在使用Rails构建一个Event站点。创建活动时,用户可以提供付费和免费活动。似乎booking_id
仅分配给付费事件而非免费活动。我检查了我的控制台,这绝对是这样的。这显然会引发问题,我不太清楚如何解决。
这是我的代码:
class BookingsController < ApplicationController
before_action :authenticate_user!
def new
# booking form
# I need to find the event that we're making a booking on
@event = Event.find(params[:event_id])
# and because the event "has_many :bookings"
@booking = @event.bookings.new
# which person is booking the event?
@booking.user = current_user
@booking.quantity = @booking.quantity
@total_amount = @booking_quantity.to_f * @event_price.to_f
end
def create
# actually process the booking
@event = Event.find(params[:event_id])
@booking = @event.bookings.new(booking_params)
@booking.user = current_user
#@total_amount = @booking.quantity.to_f * @event.price.to_f
Booking.transaction do
@booking.save!
@event.reload
if @event.bookings.count > @event.number_of_spaces
flash[:warning] = "Sorry, this event is fully booked."
raise ActiveRecord::Rollback, "event is fully booked"
end
end
if @booking.save
# CHARGE THE USER WHO'S BOOKED
# #{} == puts a variable into a string
Stripe::Charge.create(amount: @event.price_pennies, currency: "gbp",
card: @booking.stripe_token, description: "Booking number #{@booking.id}")
flash[:success] = "Your place on our event has been booked"
redirect_to event_path(@event)
else
flash[:error] = "Payment unsuccessful"
render "new"
end
if @event.is_free?
@booking.save!
flash[:success] = "Your place on our event has been booked"
redirect_to event_path(@event)
end
end
private
def booking_params
params.require(:booking).permit(:stripe_token, :quantity)
end
end
events_controller.rb
class EventsController < ApplicationController
before_action :find_event, only: [:show, :edit, :update, :destroy,]
# the before_actions will take care of finding the correct event for us
# this ties in with the private method below
before_action :authenticate_user!, except: [:index, :show]
# this ensures only users who are signed in can alter an event
def index
if params[:category].blank?
@events = Event.not_yet_happened.order("created_at DESC")
else
@category_id = Category.find_by(name: params[:category]).id
@events = Event.not_yet_happened.where(category_id: @category_id).order("created_at DESC")
end
# The above code = If there's no category found then all the events are listed
# If there is then it will show the EVENTS under each category only
end
def show
end
def new
@event = current_user.events.build
# this now builds out from a user once devise gem is added
# after initially having an argument of Event.new
# this assigns events to users
end
def create
@event = current_user.events.build(event_params)
# as above this now assigns events to users
# rather than Event.new
if @event.save
redirect_to @event, notice: "Congratulations, you have successfully created a new event."
else
render 'new'
end
end
def edit
# edit form
# @edit = Edit.find(params[:id])
@event = current_user.events.find(params[:id])
end
def update
if @event.update(event_params)
redirect_to @event, notice: "Event was successfully updated!"
else
render 'edit'
end
end
def destroy
@event.destroy
redirect_to root_path
end
private
def event_params
params.require(:event).permit(:title, :location, :date, :time, :description, :number_of_spaces, :is_free, :price, :organised_by, :url, :image, :category_id)
# category_id added at the end to ensure this is assigned to each new event created
end
def find_event
@event = Event.find(params[:id])
end
end
create_table "bookings", force: :cascade do |t|
t.integer "event_id"
t.integer "user_id"
t.string "stripe_token"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "quantity"
end
我已将@booking.save!
添加到免费事件的create方法中,但没有更改。我还添加了交易代码块以避免超额预订,但这仅适用于付费事件。任何帮助,赞赏。
答案 0 :(得分:0)
分析您的create
操作方法,我找到了以下检查:
因此create
操作可能如下所示:
def create
# actually process the booking
@event = Event.find(params[:event_id])
@booking = @event.bookings.new(booking_params)
@booking.user = current_user
#@total_amount = @booking.quantity.to_f * @event.price.to_f
if ( @event.bookings.sum(&:quantity) + @booking.quantity ) > @event.number_of_spaces
flash[:warning] = "Sorry, this event is fully booked."
redirect_to event_path(@event)
end
if @booking.save
if @event.is_free?
flash[:success] = "Your place on our event has been booked"
redirect_to event_path(@event)
else
begin
Stripe::Charge.create(
amount: @event.price_pennies,
currency: "gbp",
source: @booking.stripe_token,
description: "Booking number #{@booking.id}"
)
flash[:success] = "Your place on our event has been booked"
redirect_to event_path(@event)
rescue => e
@booking.destroy # delete the entry we have just created
flash[:error] = "Payment unsuccessful"
render "new"
end
end
end
end
当然,您需要足够好地重构代码,以确保您的控制器不会变得胖