はじめに
bootstrap導入済
namespases使用
devaice導入済
costomersモデル、ordersモデル 実装済
注文機能実装済
gimfailにenum導入して日本語で表記されるようにする
gem 'rails-i18n'
gem 'enum_help'
$ bundal install
create_table "cart_items", force: :cascade do |t|
t.integer "customer_id", null: false
t.integer "item_id", null: false
t.integer "quantity", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "order_id"
t.index ["order_id"], name: "index_cart_items_on_order_id"
end
マイグレーションを作成してCartItemにorder_idカラムをなければ追加します。
rails g migration AddOrderIdToCartItems order:references
rails db:migrate
マイグレートファイルを編集
class AddOrderIdToCartItems < ActiveRecord::Migration[6.1]
def change
add_reference :cart_items, :order, foreign_key: true, null: true
end
end
モデル
なければ追加する
class CartItem < ApplicationRecord
belongs_to :item
belongs_to :customer
+ belongs_to :order, optional: true
def subtotal
item.price_including_tax * quantity
end
end
enumを使用して注文ステータスを表示します
class Order < ApplicationRecord
belongs_to :customer
has_many :cart_items
enum order_status: {入金待ち:0, 入金確認:1, 製作中:2, 発送準備中:3, 発送済:4}
end
コントローラー
コントローラー作成
rails generate controller Admin::Orders
def index
@order = current_customer.orders
end
views 注文内容一覧ページ
<div>
<%= flash[:notice] %>
</div>
<h2>注文履歴一覧</h2>
<div class="container">
<table class="table table-bordered">
<thead>
<tr>
<th>購入日時</th>
<th>購入者</th>
<th>注文個数</th>
<th>注文ステータス</th>
</tr>
</thead>
<tbody>
<% @orders.each do |order| %>
<tr>
<td><%= order.created_at.strftime("%Y/%m/%d %H:%M") %></td>
<td><%= order.customer.last_name %><%= order.customer.first_name %></td>
<td><%= order.cart_items.sum(:quantity) %></td>
<td>
<%= form_with model: order, url: admin_order_path(order), method: :patch do |f| %>
<%= f.select :order_status, Order.order_statuses, class: "form-control" %>
<!--%= f.submit "更新", class: "btn btn-primary" %>-->
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
注文ステータスが反映されているか確認する
rails c
Order.order_statuses.key(0)
以下のようになればOK!
3.1.2 :001 > Order.order_statuses.key(0)
=> "入金待ち"
補足
OrderとCartItem間の関連付けが正しく行われていることを確認するためには、Railsコンソール(rails console)を開いて以下のようなコマンドで確かめることができます。
order = Order.first
order.cart_items
このように表示されます
ec2-user:~/environment/cakeshop (mipage) $ rails console
Running via Spring preloader in process 3824
3.1.2 :001 > order = Order.first
(0.6ms) SELECT sqlite_version(*)
Order Load (0.1ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
CartItem Load (0.1ms) SELECT "cart_items".* FROM "cart_items" WHERE "cart_items"."order_id" = ? [["order_id", 1]]
=> []
上記の出力結果から見ると、Order.first(idが1の注文)に関連付けられたCartItemが存在しないようです。つまり、最初の注文にはカートアイテムが関連付けられていないため、[](空の配列)が返されています。
ec2-user:~/environment/cakeshop (mipage) $ rails console
Running via Spring preloader in process 28248
3.1.2 :001 > order = Order.first
(1.2ms) SELECT sqlite_version(*)
Order Load (0.1ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
CartItem Load (0.2ms) SELECT "cart_items".* FROM "cart_items" WHERE "cart_items"."order_id" = ? [["order_id", 1]]
=>
[#<CartItem:0x00007f96b093d930
id: 2,
customer_id: 1,
item_id: 1,
quantity: 1,
created_at: Sun, 23 Jul 2023 23:50:24.009691000 JST +09:00,
updated_at: Sun, 23 Jul 2023 23:50:37.386020000 JST +09:00,
order_id: 1>]
このCartItem Updateという出力は、Railsが正常にCartItemを更新したことを示しています。この場合、cart_itemの'order_id'が1に設定されました。つまり、最初のOrder(Order.first)がcart_itemに関連付けられました。
その結果、cart_itemは特定のOrderに関連付けられた状態となり、これによってOrderとCartItemの間のリレーションシップが正しく機能するようになりました。