0

Ich baue eine app Events in Rails und ich habe den Fehler getroffen, über dem in meinem Modell dieser Methode bezieht -Rails Namensfehler - Nicht definierte lokale Variable oder Methode `Buchung‘

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

Der Zweck Die Methode besteht darin, eine Überbuchung eines Ereignisses zu vermeiden, bei der eine bestimmte Anzahl von Feldern verfügbar ist. In meinem Controller-habe ich den folgenden Code -

Controller # erstellen

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 

ich booking.count in meinem Controller definieren müssen aber nicht sicher, was funktionieren würde - versucht, ein paar Dinge, aber Nothings arbeiten. Ich habe folgend in meinem 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 

Die booking.count würde stützt sich auf die Menge von Räumen/Buchungen ein Benutzer im Vergleich zu der Anzahl der Räume machen möge verbleibenden aber wie drücke ich das? Benötige ich eine Spalte total_bookings in meiner Tabelle oder eine separate Methode?

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 
+1

wäre es nicht zu dem Ereignis zusammenhängen? event.booking.count? –

+0

Ihre Beziehung heißt 'Buchungen' So sollte es' bookings.count' sein –

+0

Fairer Punkt, aber ich würde immer noch den gleichen Fehler bekommen würde ich nicht? –

Antwort

0

Für den Grafen von Buchungs Tabelle, sollten Sie eine booking_count Feld in Ereignistabelle haben. Verwenden Sie dafür den Zähler-Cache. Für weitere Details überprüfen Sie http://guides.rubyonrails.org/association_basics.html. Dies ist sehr hilfreich, wenn die Datensätze groß sind.

Ihre Migration für Spalte hinzugefügt werden, sollte unter ähnlich sein:

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 
+0

Also, ich würde den counter_cache zu meinem Bookings-Modell hinzufügen und booking_count zu Ereignissen hinzufügen und in Bezug auf die obige Methode zu event.booking_count> = event.number_of_spaces? Übertragen Sie diese Methode ebenfalls von Buchung auf Ereignismodell. –

+0

Nein, behalten Sie es im Buchungsmodell und verwenden Sie den Vergleich wie event.booking_count> = event.number_of_spaces –

+0

Achten Sie darauf, den booking_count der zuvor hinzugefügten Ereignisse zu aktualisieren –

Verwandte Themen