Open2

【rails】ECサイトでの買い物カート機能の実装

かいかい

前提
必要なモデル、そのカラムは全て作成が終わっている。
基本的なルーティングも全て終わっている。
ユーザー機能が動いている
商品機能が動いている

この中での作成を始める

かいかい

ECサイトのカート機能を実装するために、cart_itemsに必要な操作を完成させるには、以下のステップを進める必要があります。cart_itemsの機能は、顧客が商品をカートに追加、更新、削除できるようにすることです。

1. CartItemsController の作成

まずはコントローラを作成します。create, update, destroy アクションを実装します。

rails generate controller public/cart_items create update destroy

次に、app/controllers/public/cart_items_controller.rb を編集して、カート機能を実装します。

class Public::CartItemsController < ApplicationController
  before_action :authenticate_customer!

  # カートに商品を追加
  def create
    @item = Item.find(params[:item_id])
    @cart_item = current_customer.cart_items.find_by(item_id: @item.id)

    if @cart_item
      # 既にカートに商品があれば数量を更新
      @cart_item.amount += params[:amount].to_i
      @cart_item.save
    else
      # 新しくカートに商品を追加
      @cart_item = current_customer.cart_items.new(cart_item_params)
      @cart_item.item = @item
      @cart_item.save
    end

    redirect_to cart_items_path
  end

  # カート内の商品を更新
  def update
    @cart_item = current_customer.cart_items.find(params[:id])
    if @cart_item.update(cart_item_params)
      redirect_to cart_items_path
    else
      render :index
    end
  end

  # カートから商品を削除
  def destroy
    @cart_item = current_customer.cart_items.find(params[:id])
    @cart_item.destroy
    redirect_to cart_items_path
  end

  # カート内の商品を表示
  def index
    @cart_items = current_customer.cart_items.includes(:item)
  end

  private

  # カートアイテムのストロングパラメータ
  def cart_item_params
    params.require(:cart_item).permit(:amount)
  end
end

2. CartItem モデルに必要なアソシエーションを追加

app/models/cart_item.rb に以下のアソシエーションを追加します。

class CartItem < ApplicationRecord
  belongs_to :customer
  belongs_to :item

  validates :amount, presence: true, numericality: { only_integer: true, greater_than: 0 }
end

3. Customer モデルにアソシエーションを追加

app/models/customer.rb に、CartItemとのアソシエーションを追加します。

class Customer < ApplicationRecord
  has_many :cart_items, dependent: :destroy
end

4. Item モデルにアソシエーションを追加

app/models/item.rb に、CartItemとのアソシエーションを追加します。

class Item < ApplicationRecord
  has_many :cart_items
end

5. ルーティングの確認

ルーティングが適切に設定されていることを確認します。以下のように、public 名前空間内で cart_items のルートが設定されていることを確認します。

namespace :public do
  resources :cart_items, only: [:index, :create, :update, :destroy] do
    delete 'destroy_all', on: :collection
  end
end

6. ビューの作成

app/views/public/cart_items/index.html.erb を作成し、カート内の商品を表示できるようにします。

<h1>カート</h1>

<% if @cart_items.present? %>
  <table>
    <thead>
      <tr>
        <th>商品名</th>
        <th>価格</th>
        <th>数量</th>
        <th>合計金額</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <% @cart_items.each do |cart_item| %>
        <tr>
          <td><%= cart_item.item.name %></td>
          <td><%= number_to_currency(cart_item.item.price) %></td>
          <td>
            <%= form_with model: cart_item, method: :patch, local: true do |f| %>
              <%= f.number_field :amount, value: cart_item.amount, min: 1 %>
              <%= f.submit '更新' %>
            <% end %>
          </td>
          <td><%= number_to_currency(cart_item.item.price * cart_item.amount) %></td>
          <td>
            <%= link_to '削除', cart_item_path(cart_item), method: :delete, data: { confirm: '削除してもよろしいですか?' } %>
          </td>
        </tr>
      <% end %>
    </tbody>
  </table>
  <div>
    <%= link_to '注文へ進む', orders_new_path %>
  </div>
<% else %>
  <p>カートに商品はありません。</p>
<% end %>

7. application.html.erb でカートアイコンを表示

カートにアイテムがある場合はカートのアイコンにアイテム数を表示するようにします。

<%= link_to cart_items_path do %>
  カート (<%= current_customer.cart_items.count %> 商品)
<% end %>

8. マイグレーションの確認

cart_items テーブルが適切に作成されていることを確認します。もしまだマイグレーションしていなければ、次のコマンドでマイグレーションを行います。

rails db:migrate

9. テスト

最後に、カート機能が正常に動作するかどうかを確認してください。商品の追加、更新、削除、カート内での表示がすべて正しく動作することをテストしましょう。

以上で、カート機能は完成です。