我正在使用Rails构建一个Event应用程序。我最近改变了我的预订控制器,以容纳免费的活动。该应用程序的这一面似乎工作正常,但当我尝试预订付费活动时,该应用程序默认为“预订不成功”'在我填写完付款表后。
我不确定为什么会这样。这是我的控制器逻辑 -
def new
@event = Event.find(params[:event_id])
@booking = Booking.new
@booking.user = current_user
end
def create
@event = Event.find(params[:event_id])
@booking = Booking.new(booking_params)
@booking.user = current_user
if
@booking.save
flash[:success] = "Your place on our event has been booked"
redirect_to event_booking_path(@event, @booking)
else
flash[:error] = "Booking unsuccessful"
render "new"
end
end
def show
@event = Event.find(params[:event_id])
@booking = Booking.find(params[:id])
end
def update
if @booking.update(booking_params)
redirect_to event_booking_path(@event, @booking) , notice: "Booking was successfully updated!"
else
render 'new'
end
end
private
def booking_params
params.require(:booking).permit(:stripe_token, :booking_number, :quantity, :event_id, :stripe_charge_id, :total_amount)
end
在我的模型中,我有这个 -
Booking.rb
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :user
before_create :set_booking_number
validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :quantity, :total_amount, :booking_number, presence: true
def set_booking_number
self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
end
def booking
# Don't process this booking if it isn't valid
self.valid?
if booking.is_free?
self.total_amount = event.price_pennies.nil?
save!
end
begin
self.total_amount = event.price_pennies * self.quantity
charge = Stripe::Charge.create(
amount: total_amount,
currency: "gbp",
source: stripe_token,
description: "Booking created for amount #{total_amount}")
self.stripe_charge_id = charge.id
self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
save!
rescue Stripe::CardError => e
errors.add(:base, e.message)
false
end
end
end
所以,由于某种原因,它不能保存或其他不正确的东西。任何帮助表示赞赏。
答案 0 :(得分:0)
这是完整的代码吗?您的&#34; booking.rb&#34;似乎完全错了。
您正在定义一种方法&#34;预订&#34;,但我没有看到您在任何地方调用它。 执行
时可能在预订方法本身if booking.is_free?
你有什么东西混在一起吗?
答案 1 :(得分:0)
好的,我们来看看。
我认为你需要这样的东西:
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :user
before_create :set_booking_number
### new
before_save(:set_total_amount)
validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :quantity, :total_amount, :booking_number, presence: true
### new
validate(:validate_booking)
def set_booking_number
self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
end
def set_total_amount
# does event.is_free? exist? if not: either define .is_free? or use self.event.price_pennies.nil? or self.event.price_pennies.to_i == 0
if self.event.is_free?
# I am guessing total_amount is an Int but you are assigning a boolean
# self.total_amount = event.price_pennies.nil?
# should be
self.total_amount = 0
else
self.total_amount = event.price_pennies * self.quantity
begin
charge = Stripe::Charge.create(
amount: total_amount,
currency: "gbp",
source: stripe_token,
description: "Booking created for amount #{total_amount}")
self.stripe_charge_id = charge.id
rescue Stripe::CardError => e
# if this fails stripe_charge_id will be null, but in case of update we just set it to nil again
self.stripe_charge_id = nil
# we check in validatition if nil
end
# booking number was already set, see set_booking_number
# self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
end
end
# is suppose to be a validation, so I renamed it
# def booking
def validate_booking
# Don't process this booking if it isn't valid
# will be called on .save anyway
# self.valid?
# I pushed this to set_total_amount (called by before_save)
# if booking.is_free?
# self.total_amount = event.price_pennies.nil?
# Why call save! ? with "!" it will cast an exception if invalid
# save!
# end
# also pushed to set_total_amount since this has nothing to do with validation
# begin
# self.total_amount = event.price_pennies * self.quantity
# charge = Stripe::Charge.create(
# amount: total_amount,
# currency: "gbp",
# source: stripe_token,
# description: "Booking created for amount #{total_amount}")
# self.stripe_charge_id = charge.id
# self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
# save!
# rescue Stripe::CardError => e
# errors.add(:base, e.message)
# false
# end
# stripe_charge_id must be set for not free events
unless self.event.is_free?
return !self.stripe_charge_id.nil?
end
end
end
这当然没有经过测试。但试一试。
我希望我的意见很清楚。
答案 2 :(得分:0)
最后突破了对params的一些工作并处理了模型代码。这是我的控制器和模型中的最终代码 -
<强> Booking.rb 强>
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :user
before_create :set_booking_number
validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 }
validate(:validate_booking)
def set_booking_number
self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase
end
def set_booking
if self.event.is_free?
self.total_amount = 0
save!
else
self.total_amount = event.price_pennies * self.quantity
begin
charge = Stripe::Charge.create(
amount: total_amount,
currency: "gbp",
source: stripe_token,
description: "Booking created for amount #{total_amount}")
self.stripe_charge_id = charge.id
save!
rescue Stripe::CardError => e
self.stripe_charge_id = nil
end
end
end
unless self.event.is_free?
return !self.stripe_charge_id.nil?
end
end
end
<强> Bookings_controller.rb 强>
class BookingsController < ApplicationController
before_action :authenticate_user!
def new
@event = Event.find(params[:event_id])
# and because the event "has_many :bookings"
@booking = Booking.new(params[:booking])
@booking.user = current_user
end
def create
# actually process the booking
@event = Event.find(params[:event_id])
@booking = @event.bookings.new(booking_params)
@booking.user = current_user
if
@booking.set_booking
flash[:success] = "Your place on our event has been booked"
redirect_to event_booking_path(@event, @booking)
else
flash[:error] = "Booking unsuccessful"
render "new"
end
if @event.is_free?
@booking.save(booking_params)
end
end
def show
@event = Event.find(params[:event_id])
@booking = Booking.find(params[:id])
end
def update
if @booking.update(booking_params)
redirect_to event_booking_path(@event, @booking) , notice: "Booking was successfully updated!"
else
render 'new'
end
end
private
def booking_params
params.require(:booking).permit(:stripe_token, :booking_number, :quantity, :event_id, :stripe_charge_id, :total_amount)
end
end