2016-09-29 2 views
1

Je reçois l'erreur ci-dessus dans mon modèle. Voici le code de modèle -Rails - NoMethodError méthode non définie `> = 'pour nil: NilClass

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 

Le code d'erreur est jeté sur cette ligne -

self.quantity >= 1 

Je crois que cela est dû à la valeur par défaut (ou l'absence de un) sur cette colonne/attribut particulier. Quel est le processus correct pour corriger cela dans les migrations? Dois-je effectuer une migration change_column_null ou change_column_default?

C'est ma table -

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 

Comme on le voit, il n'y a rien prévu pour la quantité (ni TOTAL_AMOUNT). J'ai essayé de corriger cela avec le rappel et la méthode before_validation ci-dessous, mais ils ne semblent pas fonctionner. Je crois que la migration est le seul moyen de résoudre cela, ai-je raison?

Ceci est mon code de contrôleur, y a-t-il quelque chose que je dois mettre ici?

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 

fin

+0

essayer ce, pour sauver exception self.try (: quantité)> = 1 – Navin

+0

vous dites " set "quantity," mais "> =" est un opérateur de comparaison, pas un opérateur d'affectation. Qu'est-ce que vous essayez d'atteindre dans 'set_default_values_to_greater_than_or_equal_to_zero' cette méthode? Aussi, je crois que cette méthode devrait être une méthode privée, pas publique. – Eric

+0

J'essaie de donner une valeur par défaut à quantity et total_amount, donc je n'ai pas l'erreur ci-dessus. De plus, si vous notez plus bas, je veux qu'un utilisateur puisse ajouter un certain nombre d'espaces lorsqu'il réserve un événement. Donc, un espace coûte £ 10, mais ils veulent réserver, disons, 5 espaces, donc ils devraient payer £ 50 alors total_amount = événement.prix * quantité (nombre d'espaces requis) –

Répondre

0

Si set_default_values_to_greater_than_or_equal_to_zero était une tentative de définir une valeur par défaut pour ces attributs changent >=-= parce >= est un opérateur d'évaluation qui retournera true ou false. Si vous allez dans cette voie, je suggère d'en faire une méthode privée.

Si vous souhaitez effectuer une migration à la place, pour définir les valeurs par défaut au niveau de la base de données, (que je serais en faveur de plus d'un avant le rappel de validation),

change_column_default(:bookings, :quantity, 1)

ou

change_column :bookings, :quantity, :integer, :default => 1

Voir:

change column default

change column

Comme il est indiqué dans les commentaires de page change_column_default, colonne de changement est la meilleure façon de le faire

+0

Merci. Recommanderiez-vous que je fasse aussi la migration pour total_amount? Cela semble également n'avoir aucune valeur par défaut définie dans la table des réservations. –

+0

Oui, et je voudrais supprimer ce rappel et la méthode. Si cela ne fonctionne pas, faites le moi savoir. – Eric

+0

J'ai fait la migration mais maintenant l'erreur que j'obtiens est 'le montant doit être au moins 30 pence'. Peut-être que la tangente disparaît ici, mais est-ce dû à la section de la raie? (C'est en soulignant cette ligne de mon modèle, comme ci-dessus). –