简体   繁体   中英

Rails Name Error - Undefined local variable or method `booking'

I'm building an Events app in Rails and I've hit the error above which relates to this method in my Model -

    def validate_availability
        errors.add(:base, 'event is fully booked') if booking.count >= event.number_of_spaces
    end

The purpose of the method is to avoid over-booking of an event whereby a specific number of spaces are available. In my Controller I have the following code -

Controller#Create

 def create

    @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

        if booking.count >= @event.number_of_spaces
            flash[:error] = "Sorry, this event is now fully booked"
            render "new"
        end
end

I need to define booking.count in my controller but not sure what would work - tried a few things but nothings working. I have the following in my schema -

   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",         default: 1
    t.integer  "total_amount"
    t.string   "stripe_charge_id"
    t.string   "booking_number"
  end

The booking.count would rely upon the quantity of spaces/bookings a user wishes to make versus the number of spaces remaining but how do I express this? Do I need a total_bookings column in my table or a separate method?

UPDATE -

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)
  validate(:validate_availability)

  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
            # 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

        end


  end

      def validate_booking

        # stripe_charge_id must be set for not free events
        unless self.event.is_free?
          return !self.stripe_charge_id.nil?
        end
      end

      private 

        def validate_availability
            errors.add(:base, 'event is fully booked') if event.bookings.count >= event.number_of_spaces
        end

end

For the counts of booking table, you should have a booking_count field in events table. Use the counter cache for this. For more details check http://guides.rubyonrails.org/association_basics.html . This is very helpful when records are large.

Your migration for adding column should be similar as below:

def change
    add_column :events, :bookings_count, :integer, default: 0
    Event.reset_column_information
    Event.all.each do |e|
      Event.update_counters e.id, :bookings_count => e.bookings.length
    end
  end

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