【发布时间】:2016-09-29 12:55:48
【问题描述】:
我的模型出现上述错误。这是模型代码-
Booking.rb
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :user
validates :quantity, presence: true, numericality: { greater_than: 0 }
validates :total_amount, presence: true, numericality: { greater_than: 0 }
validates :event, presence: true, numericality: {greater_than_or_equal_to: 0 }
before_validation :set_default_values_to_greater_than_or_equal_to_zero
def set_default_values_to_greater_than_or_equal_to_zero
self.quantity >= 1
self.total_amount >= 0
self.event.price >= 1 unless self.event.is_free
end
def reserve(stripe_token)
# Don't process this booking if it isn't valid
self.valid?
# We can always set this, even for free events because their price will be 0.
#self.total_amount = booking.quantity * event.price
# Free events don't need to do anything special
if event.is_free?
save!
# Paid events should charge the customer's card
else
begin
self.total_amount = event.price * 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
save!
rescue Stripe::CardError => e
errors.add(:base, e.message)
false
end
end
#end
end
end
在这一行抛出错误代码-
self.quantity >= 1
我相信这是因为此特定列/属性的默认值(或缺少默认值)。在迁移中纠正此问题的正确过程是什么?我是进行 change_column_null 迁移还是 change_column_default ?
这是我的桌子 -
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"
t.integer "total_amount"
t.string "stripe_charge_id"
end
显然,没有设置数量(也没有设置总金额)。我试图用 before_validation 回调和下面的方法来纠正这个问题,但它们似乎没有工作。我相信迁移是解决这个问题的唯一方法,对吗?
这是我的控制器代码,我需要在这里输入什么吗?
bookings_controller.rb
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(quantity: params[:quantity])
# which person is booking the event?
@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.reserve(booking_params['stripe_token'])
flash[:success] = "Your place on our event has been booked"
redirect_to event_path(@event)
else
flash[:error] = "Booking unsuccessful"
render "new"
end
end
private
def booking_params
params.require(:booking).permit(:stripe_token, :quantity, :event_id, :stripe_charge_id, :total_amount)
end
结束
【问题讨论】:
-
试试这个,以挽救异常 self.try(:quantity) >= 1
-
您说“设置”数量,但 ">=" 是比较运算符,而不是赋值运算符。你想在
set_default_values_to_greater_than_or_equal_to_zero这个方法中实现什么?另外,我认为该方法应该是私有方法,而不是公共方法。 -
我试图给数量和总金额一个默认值,所以我没有收到上述错误。此外,如果您进一步记下,我希望用户在预订活动时能够添加多个空间。所以一个空间需要 10 英镑,但他们想预订 5 个空间,因此他们需要支付 50 英镑所以 total_amount = event.price * 数量(需要的空间数量)
-
您可以根据需要在迁移中定义默认权限。
t.integer "quantity", default: 8
标签: ruby-on-rails ruby ruby-on-rails-4 rails-migrations