简体   繁体   中英

Rails - how to set default values in a model for quantity

I'm trying to allow a User to book events for more than one space at a time, so if one space at an event costs £10 and a User wants to book four spaces then they would need to pay £40. I've implemented a method in my Booking model to cater for this -

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

When I try to process a booking I get the following error -

NoMethodError in BookingsController#create undefined method `*' for nil:NilClass

This line of code is being highlighted -

self.total_amount = quantity * event.price_pennies

I need to check/make sure that quantity returns a value of 1 or more and event.price_pennies returns 0 if it is a free event and greater than 0 if it is a paid event. How do I do this?

I did not set any default values for quantity in my migrations. My schema.rb file shows this for price_pennies -

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

This is whats in my controller for create -

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

So, do I need a method in my booking model to rectify this or should I do a validation for quantity and a before_save callback for event?

I'm not quite sure how to do this so any assistance would be appreciated.

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

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

Migrations are used to modify the structure of you DB and not the data.

In your case I think you need to seed the DB with default values, and for that purpose you use 'db/seeds.rb' file which is invoked once every time your application is deployed.

You would do something like this in seeds.rb

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

So when the application is deployed the above line of code is executed. If 'my_booking' exists in the table then nothing happens, else it will create a new record with name='my_booking' and quantity=1.

In your localhost you'll execute 'rake db:seed' to seed the DB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM