2016-11-22 24 views
0

私はRailsを使ってイベントアプリを構築しています。私は最近、無料のイベントに対応するために私の予約コントローラーの周りを変更しました。このアプリの側面はうまくいくようですが、支払い済みのイベントのテスト予約をしようとすると、支払いの提出フォームを完了した後、アプリはデフォルトで「予約不成功」になります。Railsエラー - 予約に失敗

なぜこれが起こっているのか分かりません。

def new 

     @event = Event.find(params[:event_id]) 
     @booking = Booking.new 
     @booking.user = current_user 



    end 

    def create 
     @event = Event.find(params[:event_id]) 
     @booking = Booking.new(booking_params) 
     @booking.user = current_user 


      if 
       @booking.save 
       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 

    end 

    def show 
     @event = Event.find(params[:event_id]) 
     @booking = Booking.find(params[:id]) 
    end 


    def update 

     if @booking.update(booking_params) 
      redirect_to event_booking_path(@event, @booking) , notice: "Booking was successfully updated!" 
     else 
      render 'new' 
     end 
    end 




    private 

    def booking_params 
     params.require(:booking).permit(:stripe_token, :booking_number, :quantity, :event_id, :stripe_charge_id, :total_amount) 
    end 

そして、私のモデルでは、私はこれを持っている - -

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 } 
    validates :quantity, :total_amount, :booking_number, presence: true 

    def set_booking_number 
    self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase 
    end 



    def booking 
     # Don't process this booking if it isn't valid 
     self.valid? 

      if booking.is_free? 
      self.total_amount = event.price_pennies.nil? 
      save! 
      end 



      begin 
         self.total_amount = event.price_pennies * 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 
       self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase 
         save! 
        rescue Stripe::CardError => e 
        errors.add(:base, e.message) 
        false 
       end 

    end 
end 

ので、そのは保存しないか、何か他のものではない権利があります何らかの理由でここに私のコントローラロジックです。どんな援助も感謝します

+0

検証エラーを表示することによって、ビューにエラー・メッセージを参照してください - ここに私のコントローラとモデルの最後のコードです。 'フラッシュ[:エラー] = @ booking.errors.full_messages.join( '、')' – usha

+0

あなたのコードは不完全なようです...あなたの予約モデルのあなたの予約メソッドがどこから呼び出されているのかわかりませんが、あなたのコントローラから。また、あなたのモデルでどのようなバリデーションが行われているかを知ることができます。 – David

+0

完全な予約モデルコードがバリデーションとともに追加されました。何かご意見は? booking.is_freeではなく? event.is_freeを使用してif/elseステートメントにする必要がありますか? 'else'メソッドコードを支払った? (下記の他のコメントを参照してください) –

答えて

0

これは完全なコードですか?あなたの "booking.rb"は完全に間違っているようです。

メソッド "予約"を定義していますが、どこにでも呼び出すことはできません。多分あなたは

if booking.is_free? 

あなたがそこまでに何かを混ぜたのを実行予約・メソッド自体を除き ?

+0

コントローラで意味ですか? @ booking.is_freeで?モデルでは、私は無料予約と有料予約を区別しようとしています。私のイベントモデルでは、私はif_freeを持っていますか?私はここでそれらを分離しようとしているので、属性ではなく予約していません。 –

+0

大丈夫です。しかし、Booking.rbではメソッド "booking"を定義し、ライン4では "booking.is_free?"この予約はメソッド自体を参照するだけです。だから私はコードが完成したかどうか尋ねた。またはevent.is_freeを呼び出すことを意味しましたか?または何か@ booking.is_free? – Fallenhero

+0

多分完全な予約。rbは役に立ちます – Fallenhero

0

さて、見てみましょう。

私はあなたがこのようなものが必要だと思う:

class Booking < ActiveRecord::Base 

    belongs_to :event 
    belongs_to :user 
    before_create :set_booking_number 
    ### new 
    before_save(:set_total_amount) 

    validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 } 
    validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 } 
    validates :quantity, :total_amount, :booking_number, presence: true 
    ### new 
    validate(:validate_booking) 

    def set_booking_number 
    self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase 
    end 

    def set_total_amount 
    # does event.is_free? exist? if not: either define .is_free? or use self.event.price_pennies.nil? or self.event.price_pennies.to_i == 0 
    if self.event.is_free? 
     # I am guessing total_amount is an Int but you are assigning a boolean 
     # self.total_amount = event.price_pennies.nil? 
     # should be 
     self.total_amount = 0 
    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 
     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 
     # booking number was already set, see set_booking_number 
     # self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase 
    end 
    end 

    # is suppose to be a validation, so I renamed it 
    # def booking 
    def validate_booking 
    # Don't process this booking if it isn't valid 
    # will be called on .save anyway 
    # self.valid? 

    # I pushed this to set_total_amount (called by before_save) 
    # if booking.is_free? 
    #  self.total_amount = event.price_pennies.nil? 
    # Why call save! ? with "!" it will cast an exception if invalid 
    #  save! 
    # end 

    # also pushed to set_total_amount since this has nothing to do with validation 
    #  begin 
    #     self.total_amount = event.price_pennies * 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 
    #  self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase 
    #     save! 
    #    rescue Stripe::CardError => e 
    #    errors.add(:base, e.message) 
    #    false 
    #   end 

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

これはもちろんテストされていませんが。しかし、それを行ってください。

私のコメントがはっきりしていることを願います。

+0

ありがとうございます。それはすべて良い見えます。私はすでに自分自身のいくつかの変更を実装し、あなたの一部を統合しました - 上記の答えの主な問題は「保存してください!コントローラーに適切なパラメーターを渡すために必要でした。私はすぐに私の最終的なコードを掲載します。 –

0

最後に、paramsでいくつかの作業を行い、モデルコードを処理しました。

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) 

    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 
     self.stripe_charge_id = nil 

     end 
    end 
    end 

    unless self.event.is_free? 
     return !self.stripe_charge_id.nil? 
    end 
    end 
end 

Bookings_controller.rb

class BookingsController < ApplicationController 

    before_action :authenticate_user! 



    def new 
     @event = Event.find(params[:event_id]) 
     # and because the event "has_many :bookings" 
     @booking = Booking.new(params[:booking]) 
     @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.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 
    end 

    def show 
     @event = Event.find(params[:event_id]) 
     @booking = Booking.find(params[:id]) 
    end 


    def update 

     if @booking.update(booking_params) 
      redirect_to event_booking_path(@event, @booking) , notice: "Booking was successfully updated!" 
     else 
      render 'new' 
     end 
    end 




    private 

    def booking_params 
     params.require(:booking).permit(:stripe_token, :booking_number, :quantity, :event_id, :stripe_charge_id, :total_amount) 
    end 






end 
+0

それは期待どおりに機能しますか? – Fallenhero

+0

はい。これまでのすべての良い。 –

関連する問題