Dies ist eine Fortsetzung der Serie "Erstellen einer EC-Site mit Rails 5 ⑨" (https://qiita.com/GreenFingers_tk/items/3fd347dee907328d20e0), die eine EC-Site erstellt, auf der Sie in einer fiktiven Bäckerei einkaufen können. Wir werden das Order-Modell (Order-Funktion) implementieren, das die Hauptfunktion und der schwierigste Teil dieser Site ist.
Die Bewegung des Benutzers ist wie folgt.
Legen Sie den Artikel in den Warenkorb und klicken Sie auf die Schaltfläche "Weiter zum Bestellbildschirm"
↓
Bestellinformationen eingeben(orders/new)Bildschirm
·Zahlungsmethode
·Adressat
Klicken Sie auf die Schaltfläche "Weiter zum Bestätigungsbildschirm"
↓
Bestellinformationen bestätigen(orders/confirm)Bildschirm
Überprüfen Sie den Inhalt und klicken Sie auf die Schaltfläche "Bestellung bestätigen"
↓
orders/Dankesbildschirm anzeigen (statische Seite)
Sie können den Bestellverlauf auf dem Listen- und Detailbildschirm überprüfen.
Der Punkt ist, dass Sie die Lieferadresse, die auf dem Bildschirm Bestellungen / Neu eingegeben werden soll, aus "Ihre Adresse", "Registrierte Adresse" und "Neue Adresse" auswählen können. Wenn Sie eine neue Adresse auswählen und das Formular auf dem neuen Bildschirm ausfüllen, werden diese als Bestelldaten sowie als neue Daten im Adressmodell gespeichert. Das Verschachteln von Formularen und das Durchlaufen von Bestätigungsbildschirmen vor dem Speichern dieser Daten sind Faktoren, die die Implementierung dieser Funktion erschweren.
https://github.com/Sn16799/bakeryFUMIZUKI
Controller
app/controllers/orders_controller.rb
class OrdersController < ApplicationController
before_action :authenticate_customer!
before_action :set_customer
def index
@orders = @customer.orders
end
def create
if current_customer.cart_items.exists?
@order = Order.new(order_params)
@order.customer_id = current_customer.id
#Passen Sie die Argumente entsprechend der Auswahl des Optionsfelds an
@add = params[:order][:add].to_i
case @add
when 1
@order.post_code = @customer.post_code
@order.send_to_address = @customer.address
@order.addressee = full_name(@customer)
when 2
@order.post_code = params[:order][:post_code]
@order.send_to_address = params[:order][:send_to_address]
@order.addressee = params[:order][:addressee]
when 3
@order.post_code = params[:order][:post_code]
@order.send_to_address = params[:order][:send_to_address]
@order.addressee = params[:order][:addressee]
end
@order.save
# send_to_Adressmodellsuche nach Adresse, neu erstellen, wenn keine zutreffenden Daten vorhanden sind
if Address.find_by(address: @order.send_to_address).nil?
@address = Address.new
@address.post_code = @order.post_code
@address.address = @order.send_to_address
@address.addressee = @order.addressee
@address.customer_id = current_customer.id
@address.save
end
# cart_Bestellen Sie den Inhalt der Artikel_Neu in Artikeln registriert
current_customer.cart_items.each do |cart_item|
order_item = @order.order_items.build
order_item.order_id = @order.id
order_item.product_id = cart_item.product_id
order_item.quantity = cart_item.quantity
order_item.order_price = cart_item.product.price
order_item.save
cart_item.destroy #order_Nachdem Sie die Informationen in den Artikel verschoben haben, Warenkorb_Artikel wird gelöscht
end
render :thanks
else
redirect_to customer_top_path
flash[:danger] = 'Der Wagen ist leer.'
end
end
def show
@order = Order.find(params[:id])
if @order.customer_id != current_customer.id
redirect_back(fallback_location: root_path)
flash[:alert] = "Zugriff fehlgeschlagen."
end
end
def new
@order = Order.new
end
def confirm
@order = Order.new
@cart_items = current_customer.cart_items
@order.how_to_pay = params[:order][:how_to_pay]
#Passen Sie die Argumente entsprechend der Auswahl des Optionsfelds an
@add = params[:order][:add].to_i
case @add
when 1
@order.post_code = @customer.post_code
@order.send_to_address = @customer.address
@order.addressee = @customer.family_name + @customer.first_name
when 2
@sta = params[:order][:send_to_address].to_i
@send_to_address = Address.find(@sta)
@order.post_code = @send_to_address.post_code
@order.send_to_address = @send_to_address.address
@order.addressee = @send_to_address.addressee
when 3
@order.post_code = params[:order][:new_add][:post_code]
@order.send_to_address = params[:order][:new_add][:address]
@order.addressee = params[:order][:new_add][:addressee]
end
end
def thanks
end
private
def set_customer
@customer = current_customer
end
def order_params
params.require(:order).permit(
:created_at, :send_to_address, :addressee, :order_status, :how_to_pay, :post_code, :deliver_fee,
order_items_attributes: [:order_id, :product_id, :quantity, :order_price, :make_status]
)
end
end
Es wäre schön, wenn die von form_with gesendeten Informationen wie gewohnt gespeichert werden könnten, aber form_with den Bestätigungsbildschirm nicht einfügen kann. Daher rufen die Bestätigungs- und Erstellungsaktionen die aus der Ansicht empfangenen Parameter in Form von Parametern [: hoge] ab.
Außerdem können Sie beim Erstellen innerhalb einer Aktion "** Neue Bestelldaten erstellen " " Produktdaten von CartItem nach OrderItem verschieben ** (Neues Bestellelement erstellen und registriertes CartItem löschen)" ** Nur wenn das Adressmodell keine übereinstimmenden Daten enthält, müssen Sie die drei neuen Registrierungen durchführen ** ". Jede Operation ist nicht kompliziert, aber die Gesamtmenge an Code ist ziemlich groß.
View new
html:app/views/orders/.html.erb
<div class="col-lg-10 offset-1 space">
<div class="row">
<div class="col-lg-4">
<h2>Bestellinformationen eingeben</h2>
</div>
</div>
<%= form_with(model: @order, local: true, url: {action: 'confirm'}) do |f| %>
<!--Zahlungsmethode-->
<div class="row space">
<h3><strong><%= f.label :Zahlungsmethode%></strong></h3>
</div>
<div class="row">
<div class="col-lg-4 btn-group" data-toggle="buttons">
<label class="btn btn-outline-secondary active" style="width:50%">
<%= f.radio_button :how_to_pay, true, {checked: true} %>Kreditkarte
</label>
<label class="btn btn-outline-secondary" style="width:50%">
<%= f.radio_button :how_to_pay, false, {} %>Banküberweisung
</label>
</div>
</div>
<!--Adressat-->
<div class="row space">
<h3><strong><%= f.label :Adressat%></strong></h3>
</div>
<!--Eigene Adresse-->
<div class="row">
<p>
<label><%= f.radio_button :add, 1, checked: true, checked: "checked" %>Ihre eigene Adresse</label><br>
<%= @customer.post_code %>
<%= @customer.address %>
<%= @customer.full_name %>
</p>
</div>
<!--Registrierte Adresse-->
<div class="row space-sm">
<p>
<label><%= f.radio_button :add, 2, style: "display: inline-block" %>Wählen Sie aus der registrierten Adresse</label><br>
<%= f.collection_select :send_to_address, @customer.addresses, :id, :address %>
</p>
</div>
<!--Neue Adresse-->
<div class="row space-sm">
<p><label><%= f.radio_button :add, 3 %>Neues Ziel</label></p>
</div>
<div class="row">
<div class="col-lg-12">
<%= f.fields_for :new_add do |na| %>
<div class="row">
<div class="col-lg-3">
<strong>Postleitzahl(kein Bindestrich)</strong>
</div>
<div class="col-lg-6">
<%= na.text_field :post_code, class: 'form-control' %>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<strong>Adresse</strong>
</div>
<div class="col-lg-6">
<%= na.text_field :address, class: 'form-control' %>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<strong>Adresse</strong>
</div>
<div class="col-lg-6">
<%= na.text_field :addressee, class: 'form-control' %>
</div>
</div>
<% end %>
</div>
</div>
<!--Bis hierhin-->
<div class="row space">
<div class="col-lg-2 offset-lg-7">
<%= f.submit "Fahren Sie mit dem Bestätigungsbildschirm fort", class: "btn btn-danger"%>
</div>
</div>
<% end %>
</div>
confirm
html:app/views/orders/.html.erb
<div class="col-lg-10 offset-1 space">
<div class="row">
<h2>Bestellinformationen bestätigen</h2>
</div>
<%= form_with(model: @order, local: true) do |f| %>
<div class="d-none d-lg-block space">
<div class="row">
<div class="col-lg-5"><h4>Produktname</h4></div>
<div class="col-lg-2"><h4>Stückpreis (inkl. MwSt.)</h4></div>
<div class="col-lg-2"><h4>Menge</h4></div>
<div class="col-lg-2"><h4>Zwischensumme</h4></div>
</div>
</div>
<% sum_all = 0 %>
<% @cart_items.each do |cart_item| %>
<div class="row space-sm">
<div class="col-lg-3">
<%= link_to product_path(cart_item.product) do %>
<%= attachment_image_tag(cart_item.product, :image, :fill, 100, 100, fallback: "no_img.jpg ") %>
<% end %>
</div>
<div class="col-lg-2">
<%= link_to product_path(cart_item.product) do %>
<%= cart_item.product.name %>
<% end %>
</div>
<div class="col-lg-2">
<%= price_include_tax(cart_item.product.price) %>
</div>
<div class="col-lg-2">
<%= cart_item.quantity %>
</div>
<div class="col-lg-2">
<%= sum_product = price_include_tax(cart_item.product.price).to_i * cart_item.quantity %>Kreis
<% sum_all += sum_product %>
</div>
</div>
<% end %>
<div class="row space">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-3">
<strong>Versand</strong>
</div>
<div class="col-lg-3">
<%= @order.deliver_fee %>Kreis
</div>
</div>
<div class="row">
<div class="col-lg-3">
<strong>Produkt insgesamt</strong>
</div>
<div class="col-lg-3">
<%= sum_all.to_i %>Kreis
</div>
</div>
<div class="row">
<div class="col-lg-3">
<strong>Abgerechneter Betrag</strong>
</div>
<div class="col-lg-3">
<% billling_amount = sum_all + @order.deliver_fee.to_i %>
<%= billling_amount.to_i %>Kreis
</div>
</div>
</div>
</div>
<div class="row space-sm">
<div class="col-lg-2">
<h3>Zahlungsmethode</h3>
</div>
<div class="col-lg-4">
<%= how_to_pay(@order.how_to_pay) %>
</div>
</div>
<div class="row space-sm">
<div class="col-lg-2">
<h3>Adressat</h3>
</div>
<div class="col-lg-4">
<%= @order.post_code %>
<%= @order.send_to_address %>
<%= @order.addressee %>
</div>
</div>
<%= f.hidden_field :customer_id, :value => current_customer.id %>
<%= f.hidden_field :post_code, :value => "#{@order.post_code}" %>
<%= f.hidden_field :send_to_address, :value => "#{@order.send_to_address}" %>
<%= f.hidden_field :addressee, :value => "#{@order.addressee}" %>
</div>
<div class="row space">
<div class="col-lg-2 offset-lg-5">
<%= f.submit "Bestätige den Kauf", class: "btn btn-danger btn-lg" %>
</div>
</div>
<% end %>
</div>
thanks
html:app/views/orders/.html.erb
<div class="col-lg-10 offset-1 space">
<h2>Danke für Ihren Einkauf!</h2>
<h3><%= link_to 'Zurück nach oben', customer_top_path %></h3>
</div>
Diese Seite wechselt nach dem Klicken auf die Schaltfläche "Kauf bestätigen". Da es sich um eine statische Seite handelt und keine solche Funktion hat, empfiehlt es sich, nur einfache Wörter wie oben beschrieben einzugeben oder ein Foto mit einem Schieberegler usw. anzuzeigen.
index
html:app/views/orders/.html.erb
<div class="col-lg-10 offset-1 space">
<div class="row">
<h2>Bestellverlaufsliste</h2>
</div>
<div class="d-none d-lg-block space">
<div class="row">
<div class="col-lg-2">Bestelldatum</div>
<div class="col-lg-3">Lieferanschrift</div>
<div class="col-lg-2">Bestelltes Produkt</div>
<div class="col-lg-2">Zahlung</div>
<div class="col-lg-1">Status</div>
<div class="col-lg-2">Bestelldetails</div>
</div>
</div>
<% @orders.each do |order| %>
<div class="row space-sm">
<div class="col-lg-2">
<%= simple_time(order.created_at) %>
</div>
<div class="col-lg-3">
<div class="row">
<%= order.post_code + " " + order.send_to_address %>
</div>
<div class="row">
<%= order.addressee %>
</div>
</div>
<div class="col-lg-2">
<% sum_all = 0 %>
<% order.order_items.each do |order_item| %>
<%= order_item.product.name %><br>
<% sub_total = price_include_tax(order_item.order_price).to_i * order_item.quantity %>
<% sum_all += sub_total.to_i %>
<% end %>
</div>
<div class="col-lg-2">
<%= sum_all += order.deliver_fee.to_i %>Kreis
</div>
<div class="col-lg-1">
<%= order_status(order) %>
</div>
<div class="col-lg-2">
<%= link_to 'zeigen', order_path(order), class: "btn btn-sm btn-danger" %>
</div>
</div>
<% end %>
</div>
show
html:app/views/orders/.html.erb
<div class="col-lg-10 offset-1 space">
<div class="row">
<h2>Details zur Bestellhistorie</h2>
</div>
<div class="row">
<div class="col-lg-7">
<div class="row space">
<h3>Bestellinformationen</h3>
</div>
<div class="row">
<div class="container">
<div class="row space-sm">
<div class="col-lg-3">
<strong>Bestelldatum</strong>
</div>
<div class="col-lg-9">
<%= simple_time(@order.created_at) %>
</div>
</div>
<div class="row space-sm">
<div class="col-lg-3">
<strong>Lieferanschrift</strong>
</div>
<div class="col-lg-9">
<%= @order.send_to_address %>
</div>
</div>
<div class="row space-sm">
<div class="col-lg-3">
<strong>Zahlungsmethode</strong>
</div>
<div class="col-lg-9">
<%= how_to_pay(@order.how_to_pay) %>
</div>
</div>
<div class="row space-sm">
<div class="col-lg-3">
<strong>Status</strong>
</div>
<div class="col-lg-9">
<%= order_status(@order) %>
</div>
</div>
</div>
</div>
<div class="row space">
<h3>Bestelldetails</h3>
</div>
<div class="d-none d-lg-block">
<div class="row">
<div class="col-lg-4">
<strong>Produkt</strong>
</div>
<div class="col-lg-3">
<strong>Stückpreis (inkl. MwSt.)</strong>
</div>
<div class="col-lg-2">
<strong>Menge</strong>
</div>
<div class="col-lg-2">
<strong>Zwischensumme</strong>
</div>
</div>
</div>
<% sum_all = 0 %>
<% @order.order_items.each do |order_item| %>
<div class="row space-sm">
<div class="col-lg-4">
<%= order_item.product.name %>
</div>
<div class="col-lg-3">
<%= price_include_tax(order_item.order_price) %>
</div>
<div class="col-lg-2">
<%= order_item.quantity %>Stücke
</div>
<div class="col-lg-2">
<%= sub_total = price_include_tax(order_item.order_price).to_i * order_item.quantity %>Kreis
<% sum_all += sub_total %>
</div>
</div>
<% end %>
</div>
<div class="col-lg-5">
<div class="row space">
<h3>Abrechnungsdaten</h3>
</div>
<div class="row">
<div class="container">
<div class="row space-sm">
<div class="col-lg-6">
<strong>Produkt insgesamt</strong>
</div>
<div class="col-6">
<%= sum_all %>Kreis
</div>
</div>
<div class="row space-sm">
<div class="col-lg-6">
<strong>Liefergebühr</strong>
</div>
<div class="col-lg-6">
<%= @order.deliver_fee %>Kreis
</div>
</div>
<div class="row space-sm">
<div class="col-lg-6">
<strong>Abgerechneter Betrag</strong>
</div>
<div class="col-lg-6">
<%= sum_all + @order.deliver_fee.to_i %>Kreis
</div>
</div>
</div>
</div>
</div>
</div>
</div>
In der obigen Abbildung möchte ich die Gesamtmenge der Produkte in der Spalte "Rechnungsinformationen" anzeigen. Wenn ich den Bildschirm jedoch in der Reihenfolge von oben aufbaue, muss die Schleife für "Rechnungsinformationen" und "Bestelldetails" zweimal gedreht werden. Es wird ein Ärger sein. Wenn Sie also der Meinung sind, dass es sich um eine schlampige Methode handelt, teilen Sie den Bildschirm vertikal mit col in zwei Teile, erstellen Sie zuerst Spalten für "Bestellinformationen" und "Bestelldetails" und berechnen Sie dann den Gesamtbetrag in der Schleife "Bestelldetails". Es wird in einer Variablen gespeichert und im Feld "Rechnungsinformationen" aufgerufen. (In der Spalte "Rechnungsinformationen" habe ich vergessen, den Standardwert der Versandgebühr in der Datenbank festzulegen, sodass der Gesamtbetrag des Produkts und der Rechnungsbetrag gleich sind. Ursprünglich ist die Versandgebühr von 800 Yen der Rechnungsbetrag für das Gesamtprodukt. Es ist eine Spezifikation, die hinzugefügt werden muss, und der Ansichtscode entspricht auch dieser.)
Es gab nur die Kernfunktion dieser EC-Site, und die Menge an Code war groß und der Inhalt war kompliziert. In dieser Implementierung wurden Änderungen vorgenommen, z. B. die neu definierten Hilfs- und Modellmethoden, um den Code besser sichtbar zu machen und den Bildschirm ansprechbar zu machen Wurde hinzugefügt.
Es ist ein zusätzlicher Hinweis zu der Spezifikation, dass Adressdaten gleichzeitig mit der Bestellung in Adresse registriert werden, wenn in der Erstellungsaktion eine neue Adresse ausgewählt wird. In der obigen Beschreibung wird die Adressspalte des Adressmodells durchsucht und registriert, wenn keine Übereinstimmung vorliegt. Für eine genauere Suche
unless Address.find_by(addressee: @order.addressee, address: @order.send_to_address).exists?
Daher möchten Sie möglicherweise sicherstellen, dass sowohl die Adresse als auch die Adresse übereinstimmen. Obwohl der Code länger sein wird.
Auf jeden Fall vervollständigt dies die Funktionalität des Kundenstandorts. Ich bin glücklich.
Recommended Posts