【问题标题】:Rails - how to set default values in a model for quantityRails - 如何在模型中设置数量的默认值
【发布时间】:2016-09-16 12:12:51
【问题描述】:

我正在尝试允许用户一次为多个空间预订活动,因此如果活动中的一个空间花费 10 英镑,而用户想要预订四个空间,那么他们需要支付 40 英镑。 我已经在我的 Booking 模型中实现了一个方法来解决这个问题 -

Booking.rb

class Booking < ActiveRecord::Base

    belongs_to :event
    belongs_to :user

    def reserve
    # Don't process this booking if it isn't valid
    return unless valid?

    # We can always set this, even for free events because their price will be 0.
    self.total_amount = quantity * event.price_pennies

    # Free events don't need to do anything special
    if event.is_free?
      save

    # Paid events should charge the customer's card
    else
      begin
        charge = Stripe::Charge.create(amount: total_amount, currency: "gbp", card: @booking.stripe_token, description: "Booking number #{@booking.id}", items: [{quantity: @booking.quantity}])
        self.stripe_charge_id = charge.id
        save
      rescue Stripe::CardError => e
        errors.add(:base, e.message)
        false
      end
     end 
  end
end

当我尝试处理预订时,我收到以下错误 -

BookingsController#create 中的 NoMethodError nil:NilClass 的未定义方法 `*'

这行代码被高亮显示-

self.total_amount = quantity * event.price_pennies

我需要检查/确保数量返回 1 或更大的值,如果是免费活动,则 event.price_pennies 返回 0,如果是付费活动,则返回大于 0。我该怎么做呢?

我没有在迁移中为数量设置任何默认值。我的 schema.rb 文件显示了 price_pennies -

 t.integer  "price_pennies",      default: 0,     null: false

这是我的控制器中用于创建的内容 -

bookings_controller.rb

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
        flash[:success] = "Your place on our event has been booked"
        redirect_to event_path(@event)
    else
        flash[:error] = "Booking unsuccessful"
        render "new"
    end
end

那么,我是否需要在我的预订模型中使用一种方法来纠正这个问题,或者我应该对数量进行验证并为事件进行 before_save 回调?

我不太确定如何执行此操作,因此我们将不胜感激。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 model-view-controller


    【解决方案1】:

    只需转换为整数,在这种情况下你似乎已经完成了:

    self.total_amount = quantity.to_i * event.price_pennies.to_i
    

    【讨论】:

    • 介意试试吗?听起来quantity 也可能是nil
    • 是的,我认为是,如何设置模型中数量的默认值?我在迁移的时候没有设置任何东西,它需要是1或更多。
    • @Mike.Whitehead 添加迁移以将默认值添加到quantity
    • 我之前从未在迁移中手动添加默认值 - 我将如何更改现有列。
    • @Mike.Whitehead 1) 遍历每个对象,用nil 代替quantity 并将这些更新为1。2) 添加迁移
    【解决方案2】:

    迁移用于修改数据库的结构,而不是数据。

    在您的情况下,我认为您需要使用默认值播种数据库,为此您使用每次部署应用程序时调用一次的“db/seeds.rb”文件。

    你会在seeds.rb中做这样的事情

    Booking.find_or_create_by_name('my_booking', quantity:1)
    

    所以当应用程序被部署时,上面的代码行就会被执行。如果 'my_booking' 存在于表中,则不会发生任何事情,否则它将创建一条 name='my_booking' 且数量 =1 的新记录。

    在您的本地主机中,您将执行 'rake db:seed' 来为 DB 播种。

    【讨论】:

    • 那么,我可以把它直接放在种子文件中吗?我需要马上做 rake db:seed 吗?
    • @Mike.Whitehead 如果解决了您的问题,请接受我的回答。
    • 嗨,我已经尝试实现上述操作,但是当我执行 rake db:seed 时,我的命令行中出现“find_or_create_by_name”的无方法错误 - 这可能是什么?
    • 错误信息提示是 find_or_create_by 还是 find_or_create_by!哪里更合适?
    • 抱歉,我使用的是 Rails 3,我认为您使用的是 4+。您必须执行以下操作: Booking.where(name: 'my_booking', quantity: 1).first_or_create
    猜你喜欢
    • 2021-06-19
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多