カートに商品を入れる

```schema.rb
:
 create_table "cart_items", force: :cascade do |t|
    t.integer "member_id", null: false　#カート所有者(メンバー)ID(FK)
    t.integer "item_id", null: false　#商品詳細ページから引き渡すID(FK)
    t.integer "quantity", null: false　＃カート内商品の数
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
  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
  end
```

<h2>モデル設定</h2>
<p>カート内商品(cart_item)と商品(item)を結びつける</p>
<p>1 : N = item : cart_item</p>
```ruby:model/item.rb
class Item < ApplicationRecord
   :
    has_many :cart_items
   :
    validates :price, presence: true

end
```
```ruby:model/cart_item.rb
class CartItem < ApplicationRecord
    belongs_to :item
end
```
<h2>商品詳細ページで商品をカートに入れる</h2>

```ruby:member/items.controller
class Member::ItemsController < ApplicationController
 before_action :authenticate_member!, only: [:show]
:
#商品詳細ページ
def show
  @item = Item.find(params[:id])
  @cart_item =CartItem
 end

 private
 def item_params
  params.require(:items).permit(:genre_id,:name,:description,:image_id,:price)
 end
end
```
<p>form_withで情報を送る</p>
<p>f.hidden_field :item_id, :value => @item.idで文字だけでなくIDも引き渡す</p>

```html:item/show.html.erb
商品詳細ページでカートに入れるボタンを作りたい場面
<% if @item.is_active == TRUE %>　#商品販売中の場合
  <%= form_with(model: @cart_item,url: cart_items_path, method: :post,local: true)do |f| %>
   <%= f.label :quantity, "個数選択" %>
    <%= f.select :quantity, [1,2,3,4,5,6,7,8,9,10] %>
   <%= f.hidden_field :item_id, :value => @item.id %>
     #第一引数にオブジェクト名item_id、第二引数部分にvalueで受け渡す値 @item.idを指定
     #cartitem controllerの cart_items.find_by(item_id:に送ることができる
   <%= f.submit "カートに入れる" %>
  <% end %>
<% end %>

```

<h2>カート内商品　一覧ページを作る</h2>
<p>カートモデル(中間テーブル?)を使う方法もあるらしいが今回は使わない方法で記載</p>
<p></p>
```ruby:cart_items.controller.rb
class Member::CartItemsController < ApplicationController
   before_action :authenticate_member!
    def index
        @cart_items = current_member.cart_items.all
    end
    # カート商品を追加・保存
    def create
        @cart_item = current_member.cart_items.new(cart_item_params)
        # もし元々カート内に「同じ商品」がある場合、「数量を追加」更新・保存する
        #ex.バナナ２個、バナナ２個ではなく　バナナ「4個」にしたい
        if current_member.cart_items.find_by(item_id: params[:cart_item][:item_id]).present?
                          #元々カート内にあるもの「item_id」　
                          #今追加した　　　　　　　params[:cart_item][:item_id])
            cart_item = current_member.cart_items.find_by(item_id: params[:cart_item][:item_id])
            cart_item.quantity += params[:cart_item][:quantity].to_i
           #cart_item.quantityに今追加したparams[:cart_item][:quantity]を加える
                                                              #.to_iとして数字として扱う
            cart_item.save
            redirect_to cart_items_path

        # もしカート内に「同じ」商品がない場合は通常の保存処理 
        elsif @cart_item.save
            　@cart_items = current_member.cart_items.all
            　render 'index'
        else　# 保存できなかった場合
            render 'index'
        end
    end
:
private
    def cart_item_params
        params.require(:cart_item).permit(:item_id, :price, :quantity)
    end
end

```

<h2></h2>
<p></p>

```html:cart_item/index.html.erb
<h4>ショッピングカート</h4>
<table>
   <tr>
    <th>商品名</th>
    <th>単価(税込)</th>
    <th>数量</th>
    <th>小計</th>
    <th></th>
   </tr>
     <% total = 0 %>　#合計金額totalの初期化
 
 <% if current_member.cart_items.present? %> #カート内に商品があった場合
    <% @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>　#商品単価(価格×1.08)
       <td>
         <%= form_with model: cart_item, url: cart_item_path(cart_item), local: true, method: :patch do |f| %>
           <%= f.number_field :quantity, min: 1, max:10, id: "quantity_cart"%>
           <%= f.submit "変更",class: "btn btn-success" %> #セレクトboxで数量変更
         <% end %>
       </td>
       <td>
         <% subtotal = ((cart_item.item.price*cart_item.quantity)*1.08).to_i %>　#小計を計算する
         <%= subtotal %> #小計を表示
       </td>
       <td>
         <%= link_to "商品をカートから削除する", cart_item_path(cart_item.id, cart_item), method: :delete,class: "btn btn-danger" %>
       </td>
     </tr>
       <% total += subtotal %>　#アイテムごとに合計金額totalに反映 計算しておく
     <% end %>
<% end %>
   <tr>    
    <th>合計金額</th>
    <td><%= total %></td>
   </tr>
 
```
<h2>カートを空にする作業</h2>
<p>orders_controller内でcart内の商品データを移す操作をあとでする</p>
```routes.rb
resources :cart_items,only: [:index,:create,:update,:destroy] do
      collection do
        delete "all_destroy"   #パスが　all_destroy_cart_items_path, method: :delete　となる
      end 
    end
```
```ruby:cart_item.controller.rb
   def destroy
        cart_item = CartItem.find(params[:id])
        cart_item.destroy
        @cart_items = CartItem.all
        　render 'index'
    end
      
    def all_destroy  #カート内全て削除
        cart_items = CartItem.all
        cart_items.destroy_all
        　render 'index'
    end
```

```html:cart_item/index.html.erb
:
  <%= link_to "カートを空にする", all_destroy_cart_items_path, method: :delete,class: "btn btn-danger btn-sm" %>

```

<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```
<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```

<h2></h2>
<p></p>
```
```
<h2></h2>
<p></p>
```
```