7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

カートに商品を入れる

Last updated at Posted at 2021-08-28
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

モデル設定

カート内商品(cart_item)と商品(item)を結びつける

1 : N = item : cart_item

```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

商品詳細ページで商品をカートに入れる

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

form_withで情報を送る

f.hidden_field :item_id, :value => @item.idで文字だけでなくIDも引き渡す

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 %>

カート内商品 一覧ページを作る

カートモデル(中間テーブル?)を使う方法もあるらしいが今回は使わない方法で記載

```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.バナナ2個、バナナ2個ではなく バナナ「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>
 

カートを空にする作業

orders_controller内でcart内の商品データを移す操作をあとでする

```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" %>

``` ```

``` ```

``` ```

``` ```

``` ```

``` ```

``` ```

``` ```

``` ```

``` ```
7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?