2016-08-10 4 views
0

Ich baue eine Events App mit Rails. Momentan erlaubt der Buchungsprozess nur einem Benutzer, einen Platz pro Buchung zu buchen. Ich muss die Möglichkeit hinzufügen, wodurch ein Benutzer mehrere/Gruppenbuchungen auf einmal machen kann. Also brauche ich nicht nur eine "Quantity" -Funktion, ich brauche das auch, um mit dem Preis übereinzustimmen. Ich habe SO und Google durchsucht und versucht, die Antworten zu finden, habe aber nichts erreicht, was für die meisten Websites ziemlich üblich ist.Rails - wie mehrere Buchungen für denselben Benutzer hinzugefügt werden

Ich nehme an, ich brauche ein Verfahren irgendeiner Art (im Modell?) -

def total_amount 
    @booking.quantity * @event.price 
end 

Also, wenn jemand für 10 Räume auf einer Veranstaltung buchen möchte, der dann den Gesamtbetrag £ 10 pro Raum kostet sollte sich auf £ 100 anrechnen.

Verwende ich Methoden in meinem Modell/Controller oder benötige ich Javascript um den Preis pro Gruppenbuchung zu reflektieren?

Hier ist der MVC-Code für die Buchungen -

Booking.rb

 class Booking < ActiveRecord::Base 

    belongs_to :event 
    belongs_to :user 





end 

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 
     # which person is booking the event? 
     @booking.user = current_user 
     #@booking.quantity = @booking.quantity 
     #@total_amount = @booking_quantity.to_f * @event_price.to_f 

    end 




def create 
     # actually process the booking 
     @event = Event.find(params[:event_id]) 
     @booking = @event.bookings.new(booking_params) 
     @booking.user = current_user 
     #@total_amount = @booking.quantity.to_f * @event.price.to_f 

     Booking.transaction do 

      @event.reload 
      if @event.bookings.count > @event.number_of_spaces 
      flash[:warning] = "Sorry, this event is fully booked." 
      raise ActiveRecord::Rollback, "event is fully booked" 
      end 
     end 




     if @booking.save 

      # CHARGE THE USER WHO'S BOOKED 
      # #{} == puts a variable into a string 
      Stripe::Charge.create(amount: @event.price_pennies, currency: "gbp", 
       card: @booking.stripe_token, description: "Booking number #{@booking.id}") 

      flash[:success] = "Your place on our event has been booked" 
      redirect_to event_path(@event) 
     else 
      flash[:error] = "Payment unsuccessful" 
      render "new" 
     end 

     if @event.is_free? 

      @booking.save! 
      flash[:success] = "Your place on our event has been booked" 
      redirect_to event_path(@event) 
     end 
    end 



    private 

    def booking_params 
     params.require(:booking).permit(:stripe_token, :quantity) 
    end 



end 

new.html.erb (Buchungen)

   <% if @event.is_free? %> 
<div class="col-md-6 col-md-offset-3" id="eventshow"> 
    <div class="row"> 
    <div class="panel panel-default"> 
     <div class="panel-heading"> 
      <h2>Your Booking Confirmation</h2> 
     </div> 
       <div class="panel-body"> 

         <h1>Hi there</h1> 

         <p>You have placed a booking on <%= @event.title %></p> 

         <p>Your order number is <%= @booking.id %></p> 

         <p>We hope you have a wonderful time. Enjoy!</p> 

         <p>Love from Mama Knows Best</p> 
       </div>   
        <div class="panel-footer"> 
        <%= link_to "Home", root_path %> 
        </div> 
    </div> 
    </div> 
</div>      

       <% else %> 

<div class="col-md-6 col-md-offset-3" id="eventshow"> 
    <div class="row"> 
    <div class="panel panel-default"> 
     <div class="panel-heading"> 
      <h2>Confirm Your Booking</h2> 
     </div> 

      <div class="panel-body">  

       <p>Total Amount<%= @event.price %></p> 
       <%= simple_form_for [@event, @booking], id: "new_booking" do |form| %> 





       <span class="payment-errors"></span> 

       <div class="form-row"> 
        <label> 
         <span>Card Number</span> 
         <input type="text" size="20" data-stripe="number"/> 
        </label> 
       </div> 

       <div class="form-row"> 
        <label> 
        <span>CVC</span> 
        <input type="text" size="4" data-stripe="cvc"/> 
        </label> 
       </div> 

       <div class="form-row"> 
        <label> 
         <span>Expiration (MM/YYYY)</span> 
         <input type="text" size="2" data-stripe="exp-month"/> 
        </label> 
        <span>/</span> 
        <input type="text" size="4" data-stripe="exp-year"/> 
       </div> 
      </div> 
      <div class="panel-footer">  

       <%= form.button :submit %> 


      </div> 

<% end %> 
<% end %> 

     </div> 
    </div> 
</div>  

<script type="text/javascript" src="https://js.stripe.com/v2/"></script> 

<script type="text/javascript"> 
    Stripe.setPublishableKey('<%= STRIPE_PUBLIC_KEY %>'); 
    var stripeResponseHandler = function(status, response) { 
    var $form = $('#new_booking'); 

    if (response.error) { 
    // Show the errors on the form 
    $form.find('.payment-errors').text(response.error.message); 
    $form.find('input[type=submit]').prop('disabled', false); 
    } else { 
    // token contains id, last4, and card type 
    var token = response.id; 
    // Insert the token into the form so it gets submitted to the server 
    $form.append($('<input type="hidden" name="booking[stripe_token]"  />').val(token)); 
    // and submit 
    $form.get(0).submit(); 
    } 
    }; 

    // jQuery(function($) { - changed to the line below 
    $(document).on("ready page:load", function() { 

    $('#new_booking').submit(function(event) { 
     var $form = $(this); 

     // Disable the submit button to prevent repeated clicks 
     $form.find('input[type=submit]').prop('disabled', true); 

     Stripe.card.createToken($form, stripeResponseHandler); 

     // Prevent the form from submitting with the default action 
     return false; 
    }); 
    }); 
</script> 

Hier ist das Schema für Buchungen und Veranstaltungen -

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" 
    end 

create_table "events", force: :cascade do |t| 
t.string "title" 
t.string "location" 
t.date  "date" 
t.time  "time" 
t.text  "description" 
t.string "organised_by" 
t.datetime "created_at",       null: false 
t.datetime "updated_at",       null: false 
t.integer "user_id" 
t.string "image_file_name" 
t.string "image_content_type" 
t.integer "image_file_size" 
t.datetime "image_updated_at" 
t.integer "category_id" 
t.string "url" 
t.integer "number_of_spaces" 
t.integer "price" 
t.boolean "is_free" 
t.integer "price_cents",  default: 0,  null: false 
t.integer "price_pennies",  default: 0,  null: false 
t.string "price_currency",  default: "GBP", null: false 
t.boolean "happened",   default: false 
    end 

Ich denke, im Idealfall, ich brauche eine ergänzende Teil Form aktiviert, wenn ein Benutzer klickt auf ‚Buch der Veranstaltung‘, die sie die angeben, fragt Anzahl der Plätze, die sie für die Veranstaltung buchen möchten, BEVOR sie mit der Zahlung beginnen. Irgendwelche Hilfe oder Stoß in die richtige Richtung würden geschätzt.

Antwort

0

Erstellen eines virtuellen Attributs (wie Sie vorgeschlagen) im Modell Buchung mit dem Gesamtpreis ist ein guter Weg.

booking.rb:

def total_amount 
    self.quantity * self.event.price 
end 

der Benutzer Lassen Sie die Anzahl der Räume angeben, bevor er die Seite Bestätigung sieht (zumindest für eine bessere UX). Stellen Sie standardmäßig auf 1. übertragen Sie die Anzahl der Räume zu der ‚neuen‘ Methode:

def new 
    .... 
    @booking = @event.bookings.new(quantity: params[:quantity]) 
    .... 

end 

Jetzt können Sie sich anzeigen lassen oder den Gesamtpreis Zugriff mit

<p>Total Amount<%= @booking.total_amount %></p> 
+0

Also macht ich einen ergänzenden Teil bauen oder schließen Das alles in der Zahlungsform? Würde das überhaupt funktionieren? –

+0

Sie brauchen keine teilweise. Stellen Sie sich total_price als reguläres Attribut vor. Es muss funktionieren – user1201917

+0

Wo sollte ich den Benutzer die Anzahl der Leerzeichen angeben, obwohl, in der neuen.html Form oben? Füge ich einfach ein Eingabeformular ein? –

Verwandte Themen