マイグレーションファイルを確認
テーブルデータ
```ruby:schema create_table "items", force: :cascade do |t| t.integer "genre_id", null: false t.string "name", null: false t.text "description", null: false t.string "image_id", null: false t.integer "price", null: false t.boolean "is_active", default: true, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false endcreate_table "ordered_items", force: :cascade do |t|
t.integer "order_id", null: false
t.integer "item_id", null: false
t.integer "quantity", null: false
t.integer "making_status", default: 0, null: false
t.integer "tax_included_price", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "orders", force: :cascade do |t|
t.integer "member_id", null: false
t.integer "postage", null: false
t.integer "total_payment", null: false
t.integer "payment_method", default: 0, null: false
t.string "shipping_name", null: false
t.string "shipping_address", null: false
t.string "shipping_post_code", null: false
t.integer "status", default: 0, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
<h2>order⇄ordered_item(中間) ⇄ item モデル設定する</h2>
<p>order ⇄ ordered_item ⇄ item</p>
<p>多:多になるので中間テーブルを介してデータやりとりする</p>
```ruby:model/order.rb
class Order < ApplicationRecord
:
has_many :ordered_items #中間テーブル
has_many :items, through: :ordered_items #注文には商品が多くある
enum status: {
"入金待ち":0,
"入金確認":1,
"製作中":2,
"発送準備中":3,
"発送済み":4
}
enum payment_method: ["クレジットカード", "銀行振込"]
end
ordered_item.rb 中間テーブル
```model/ordered_item.rb class OrderedItem < ApplicationRecord belongs_to :order belongs_to :item ```コントローラー
```ruby:orders.controller class Member::OrdersController < ApplicationController before_action :authenticate_member! def new # 注文情報入力画面 @order = Order.new @addresses = current_member.addresses.all end : ```住所を(0)[自分の住所](1)[アドレス張](2)[新規]から選択する
注文情報入力画面 new.htmlで条件分けてformを送り、
def confirmでデータを設定し直す
データを入力し送る→データを保存せずにそのまま表示→次の画面でデータ保存の流れ
(0)まずは[自分の住所]の時
```html:orders/new.html.erb注文情報入力
<%= form_with model: @order, url: "/orders/confirm", method: :post, local: true do |f| %> :お届け先
#[:address_option]=="0"として設定する <%= f.radio_button :address_option, 0, checked: "checked" %> #checked:予めbuttn選択される <%= f.label :order_address, "ご自身の住所" %>〒<%= current_member.post_code %> #郵便番号 <%= current_member.address %>
#住所 <%= current_member.last_name %><%= current_member.first_name %> #名前
: <%end%> ```
new.htmlの[:address_option]=="0データをdef confirmで移す
class Member::OrdersController < ApplicationController
before_action :authenticate_member!
def confirm # 注文情報入力確認画面
@order = Order.new(order_params)
# [:address_option]=="0"のデータ(memberの住所)を呼び出す
if params[:order][:address_option] == "0"
@order.shipping_post_code = current_member.post_code
@order.shipping_address = current_member.address
@order.shipping_name = current_member.last_name + current_member.first_name
:
end
:
private
def order_params
params.require(:order).permit(:postage, :payment_method, :shipping_name, :shipping_address, :shipping_post_code ,:member_id,:total_payment,:status)
end
end
(1)[アドレス張]から情報を表示させてデータを送る
```html:new.html.erb <%= form_with model: @order, url: "/orders/confirm", method: :post, local: true do |f| %> : <%= f.radio_button :address_option, 1 %> #[:address_option]=="1"が呼出 送る <%= f.label :order_address, "登録済住所から選択" %><%= f.collection_select :member_id, @addresses, :id, :full_adresses %> #第一引数メソッド名 :member_id にひもづく adresses : #コントローラの @addresses = current_member.addresses.all : # :id, :full_adresses カラムとってくる : <%end%> ```
new.htmlの[:address_option]=="1" データをdef confirmで移す
```ruby:orders.controller.rb def confirm # 注文情報入力確認画面 @order = Order.new(order_params) : # [:address_option]=="1"を呼び出す elsif params[:order][:address_option] == "1" ship = Address.find(params[:order][:member_id]) #orderのmember_id(=カラム)でアドレス(帳)を選び、そのデータ送る @order.shipping_post_code = ship.post_code @order.shipping_address = ship.address @order.shipping_name = ship.name ```(2)[新規]で住所入力 text_fieldに入れてもらう
```html:new.html.erb <%= form_with model: @order, url: "/orders/confirm", method: :post, local: true do |f| %> : #[:address_option]=="2"として,text_field に入れたデータを送る <%= f.radio_button :address_option, 2 %> <%= f.label :order_address, "新しいお届け先" %><%= f.label :shipping_post_code, "郵便番号(ハイフンなし)" %> | <%= f.text_field :shipping_post_code %> |
<%= f.label :shipping_address, "住所" %> | <%= f.text_field :shipping_address %> |
<%= f.label :shipping_name, "宛名" %> | <%= f.text_field :shipping_name %> |
new.htmlの[:address_option]=="2" text_fieldデータをdef confirmで移す
def confirm # 注文情報入力確認画面
@order = Order.new(order_params)
:
# 新規住所入力 [:address_option]=="2"としてデータをhtmlから受ける
elsif params[:order][:address_option] = "2"
@order.shipping_post_code = params[:order][:shipping_post_code]
@order.shipping_address = params[:order][:shipping_address]
@order.shipping_name = params[:order][:shipping_name]
else
render 'new'
end
:
注文情報入力画面に 支払い方法もかく
new.html.erbでは支払い方法も入力するので追記
```html:order/new.html.erb注文情報入力
<%= form_with model: @order, url: "/orders/confirm", method: :post, local: true do |f| %>支払い方法
<%= f.radio_button :payment_method,:クレジットカード,checked: "checked" %>
<%= f.label :payment_method, "クレジットカード" %>
<%= f.radio_button :payment_method, :銀行振込 %>
<%= f.label :payment_method, "銀行振込" %>
お届け先
: <%= f.radio_button :address_option, 0, checked: "checked" %> :(以下:上に記載したもの) : <%end%> ```注文確認 orders/confirm.html.erb
def confirm
@order = Order.new(order_params)
:
: #params[:order][:address_option] == "0"から"2"の 住所データを定義する
: @order.shipping_post_code =
: @order.shipping_address =
: @order.shipping_name =
: :
:
@cart_items = current_member.cart_items.all
end
分岐で定義したおかげで、お届け先が表示できる
```html:confirm.html.erb注文情報確認
支払い方法 <%= @order.payment_method %> お届け先 <%= @order.shipping_post_code %> #郵便番号 <%= @order.shipping_address %> #住所 <%= @order.shipping_name %> #名前 ```カート商品をconfirm注文確認画面で表示させる
```ruby:OrdersController class Member::OrdersController < ApplicationController before_action :authenticate_member! # 注文情報入力確認画面 def confirm @order = Order.new(order_params) : (上記記載) : @cart_items = current_member.cart_items.all end ``` ```html:confirm.html.erb注文情報確認
商品名 | 単価(税込) | 数量 | 小計 | <% total = 0 %> #合計金額total初期化 <% @cart_items.each do |cart_item| %>
---|---|---|---|
<%= attachment_image_tag(cart_item.item, :image, size: "60x50", fallback: "no_image.jpg") %> <%= cart_item.item.name %> | <%= (cart_item.item.price*1.08).to_i %> | <%= cart_item.quantity %> | <% subtotal = ((cart_item.item.price*cart_item.quantity)*1.08).to_i %> <%= subtotal %>#小計を表示 |
送料 | <% @order.postage = 800 %><%= @order.postage %> |
---|---|
商品合計 | <%= total.to_i %> |
請求金額 | <% @order.total_payment = @order.postage + total.to_i %><%= @order.total_payment %> |
注文確認画面でorderを保存
```ruby:OrdersController class Member::OrdersController < ApplicationController before_action :authenticate_member! : def create @order = Order.new(order_params) @order.save : end : private def order_params params.require(:order).permit(:postage, :payment_method, :shipping_name, :shipping_address, :shipping_post_code ,:member_id,:total_payment,:status) end end
```html:orders/confirm.html.erb
:
<%= form_with model: @order, url: orders_path, method: :post, local: true do |f| %>
<%= f.hidden_field :member_id %>
<%= f.hidden_field :postage %>
<%= f.hidden_field :total_payment %>
<%= f.hidden_field :payment_method %>
<%= f.hidden_field :shipping_name %>
<%= f.hidden_field :shipping_address %>
<%= f.hidden_field :shipping_post_code %>
<%= f.hidden_field :status %>
<%= f.submit "注文を確定する", class: "btn btn-success" %>
<% end %>
カートは空にするのでordered_itemに保存しておく
```ruby: def create @order = Order.new(order_params) @order.member_id = current_member.id @order.saveordered_itmemに保存
current_member.cart_items.each do |cart_item| #カート内商品を1つずつ取り出しループ
@ordered_item = OrderedItem.new #初期化宣言
@ordered_item.order_id = @order.id #order注文idを紐付けておく
@ordered_item.item_id = cart_item.item_id #カート内商品idを注文商品idに代入
@ordered_item.quantity = cart_item.quantity #カート内商品の個数を注文商品の個数に代入
@ordered_item.tax_included_price = (cart_item.item.price*1.08).floor #消費税込みに計算して代入
@ordered_item.save #注文商品を保存
end #ループ終わり
current_member.cart_items.destroy_all #カートの中身を削除
redirect_to thanx_orders_path
end
<h2></h2>
<p></p>
<h2></h2>
<p></p>
<h2></h2>
<p></p>
```ruby:OrdersController
class Member::OrdersController < ApplicationController
before_action :authenticate_member!
# 注文情報入力画面
def new
@order = Order.new
@addresses = current_member.addresses.all
end
# 注文情報入力確認画面
def confirm
@order = Order.new(order_params)
# @orderはでかい箱で、その中に小さい箱を指定するためにストロングパラメーターを指定している。
# if文を記述して、hidden fieldが作動するようにする。
# ご自身の住所と配送先住所が選択された場合はhiddenで処理
# 現在memberに登録されている住所であれば
if params[:order][:address_option] == "0"
@order.shipping_post_code = current_member.post_code
@order.shipping_address = current_member.address
@order.shipping_name = current_member.last_name + current_member.first_name
# collection.selectであれば
elsif params[:order][:address_option] == "1"
ship = Address.find(params[:order][:member_id])
@order.shipping_post_code = ship.post_code
@order.shipping_address = ship.address
@order.shipping_name = ship.name
# 新規住所入力であれば
elsif params[:order][:address_option] = "2"
@order.shipping_post_code = params[:order][:shipping_post_code]
@order.shipping_address = params[:order][:shipping_address]
@order.shipping_name = params[:order][:shipping_name]
else
render 'new'
end
@cart_items = current_member.cart_items.all
@order.member_id = current_member.id
end
# 注文情報保存
def create
@order = Order.new(order_params)
@order.member_id = current_member.id
@order.save
# ordered_itmemの保存
current_member.cart_items.each do |cart_item| #カートの商品を1つずつ取り出しループ
@ordered_item = OrderedItem.new #初期化宣言
@ordered_item.item_id = cart_item.item_id #商品idを注文商品idに代入
@ordered_item.quantity = cart_item.quantity #商品の個数を注文商品の個数に代入
@ordered_item.tax_included_price = (cart_item.item.price*1.08).floor #消費税込みに計算して代入
@ordered_item.order_id = @order.id #注文商品に注文idを紐付け
@ordered_item.save #注文商品を保存
end #ループ終わり
current_member.cart_items.destroy_all #カートの中身を削除
redirect_to thanx_orders_path
end
# 注文完了画面
def thanx
end
# 注文情報履歴一覧
def index
@orders = current_member.orders
end
# 注文情報詳細
def show
@order = Order.find(params[:id])
@ordered_items = @order.ordered_items
end
private
def order_params
params.require(:order).permit(:postage, :payment_method, :shipping_name, :shipping_address, :shipping_post_code ,:member_id,:total_payment,:status)
end
end
支払い方法
<%= f.radio_button :payment_method,:クレジットカード, checked: "checked" %>
<%= f.label :payment_method, "クレジットカード" %>
<%= f.radio_button :payment_method, :銀行振込 %>
<%= f.label :payment_method, "銀行振込" %>
お届け先
<%= f.radio_button :address_option, 0, checked: "checked" %>
<%= f.label :order_address, "ご自身の住所" %>
<br>
〒<%= current_member.post_code %>
<%= current_member.address %><br>
<%= current_member.last_name %>
<%= current_member.first_name %>
<br>
<%= f.radio_button :address_option, 1 %>
<%= f.label :order_address, "登録済住所から選択" %>
<br>
<%= f.collection_select :member_id, @addresses, :id, :full_adresses %>
<br>
<%= f.radio_button :address_option, 2 %>
<%= f.label :order_address, "新しいお届け先" %>
<table>
<tr>
<td class='col-3'><%= f.label :shipping_post_code, "郵便番号(ハイフンなし)" %></td>
<td class='col-9'><%= f.text_field :shipping_post_code, :placeholder => "1234567"%></td>
</tr>
<tr>
<td class='col-3'><%= f.label :shipping_address, "住所" %></td>
<td class='col-9'><%= f.text_field :shipping_address, :placeholder => "東京都渋谷区代々木", class: "w-100" %></td>
</tr>
<tr>
<td class='col-3'><%= f.label :shipping_name, "宛名" %></td>
<td class='col-9'><%= f.text_field :shipping_name, :placeholder => "山田花子" %></td>
</tr>
</table>
<div class="row justify-content-center py-5">
<%= f.submit "確認画面へ進む" , class:"btn btn-primary" %>
</div>
<% end %>
</div>
</div>
```html:orders/confirm.html.erb
<div "container">
<div class='row mb-3'>
<div class='col-8 offset-1'>
<h4 class="pt-3">注文情報確認</h4>
</div>
</div>
<div class='row'>
<div class='col-7 offset-1'>
<table class='table table-bordered border-dark'>
<tr class="table-secondary">
<th>商品名</th>
<th>単価(税込)</th>
<th>数量</th>
<th>小計</th>
</tr>
<!--合計金額totalの初期化-->
<% total = 0 %>
<% @cart_items.each do |cart_item| %>
<tr>
<td><%= attachment_image_tag(cart_item.item, :image, size: "60x50", fallback: "no_image.jpg") %>
<%= cart_item.item.name %></td>
<td><%= (cart_item.item.price*1.08).to_i %></td>
<td><%= cart_item.quantity %></td>
<td>
<!--小計の計算-->
<% subtotal = ((cart_item.item.price*cart_item.quantity)*1.08).to_i %>
<!--小計を表示-->
<%= subtotal %>
</td>
</tr>
<!--アイテムごとに合計金額に加算する-->
<% total += (cart_item.item.price*cart_item.quantity)*1.08 %>
<% end %>
</table>
</div>
<div class='col-3'>
<table class="table table-bordered border-dark">
<% @order.postage = 800 %>
<tr><th class="table-secondary">送料</th><td><%= @order.postage %></td></tr>
<tr><th class="table-secondary">商品合計</th><td><%= total.to_i %></td></tr>
<% @order.total_payment = @order.postage + total.to_i %>
<tr><th class="table-secondary">請求金額</th><td><%= @order.total_payment %></td></tr>
</table>
</div>
</div>
<div class="row">
<div class='col-11 offset-1'>
<table class="table table-borderless">
<tr><th class="col-1">支払い方法</th><td class="col-10"><%= @order.payment_method %></td></tr>
<tr><th class="col-1">お届け先</th><td class="col-10">
<%= @order.shipping_post_code %>
<%= @order.shipping_address %>
<%= @order.shipping_name %>
</td></tr>
</table>
</div>
</div>
<div class="row justify-content-center">
<%= form_with model: @order, url: orders_path, method: :post, local: true do |f| %>
<%= f.hidden_field :member_id %>
<%= f.hidden_field :postage %>
<%= f.hidden_field :total_payment %>
<%= f.hidden_field :payment_method %>
<%= f.hidden_field :shipping_name %>
<%= f.hidden_field :shipping_address %>
<%= f.hidden_field :shipping_post_code %>
<%= f.hidden_field :status %>
<%= f.submit "注文を確定する", class: "btn btn-success" %>
<% end %>
</div>
</div>