学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Rails導入編 | カート機能の実装 | 15 | セッションカートの改良

↓↓クリックして頂けると励みになります。




14 | セッションカートの実装】 << 【ホーム】 >> 【16 | エラー処理





カート内の商品の数量を実装します。
カートの各商品に数量を対応付けるためには「line_itemsテーブル」を修正する必要があります。
ターミナルで以下のコマンドを入力します。
コマンド
rails generate migration add_quantity_to_line_items quantity:bigint

~/Desktop/Rails7_1/SampleCart $ rails generate migration add_quantity_to_line_items quantity:bigint

      invoke  active_record
      create    db/migrate/20240118235653_add_quantity_to_line_items.rb



Railsはマイグレーションの名前から「line_itemsテーブル」に列を追加しようとしているのだと認識し、各列の名前とデータ型を最後の引数から取得します。
Railsが認識するパターンは「add_XXX_to_TABLE」と「remove_XXX_from_TABLE」の2つです。
XXXの部分は無視されます。
カートに追加された商品の数量のデフォルト値が1となるようにマイグレーションファイルを修正します。
「SampleCart/db/migrate」フォルダに出来た「20240118235653_add_quantity_to_line_items.rb」ファイルを以下のように編集します。
3行目に「, default: 1」の記述を追加しています。


記述追加 【SampleCart/db/migrate/20240118235653_add_quantity_to_line_items.rb】3行目

class AddQuantityToLineItems < ActiveRecord::Migration[7.1]
  def change
    add_column :line_items, :quantity, :bigint, default: 1
  end
end



マイグレーションを実行します。
ターミナルで以下のコマンドを入力します。
コマンド
rails db:migrate

~/Desktop/Rails7_1/SampleCart $ rails db:migrate

== 20240118235653 AddQuantityToLineItems: migrating ===========================
-- add_column(:line_items, :quantity, :bigint, {:default=>1})
   -> 0.0221s
== 20240118235653 AddQuantityToLineItems: migrated (0.0223s) ==================



次に「add_good()」メソッドをCartモデルに作成します。
このメソッドはこれから追加しようとしている商品がLineItemsに含まれているかどうか確認して、含まれていれば数量を増やして、含まれていなければ新たにLineItemを作成します。


「SampleCart/app/models」フォルダにある「cart.rb」ファイルに「add_goog()」メソッドの記述を追加します。


記述追加 【SampleCart/app/models/cart.rb】

class Cart < ApplicationRecord
    has_many :line_items, dependent: :destroy

    def add_good(good)
		current_item = line_items.find_by(good_id: good.id)
		if current_item
			current_item.quantity += 1
		else
			current_item = line_items.build(good_id: good.id)
		end
		current_item

	end
end



「line_items」コントローラにも修正を加えてこの「add_goog()」メソッドを使用するようにします。
「SampleCart/app/controllers」フォルダにある「line_items_controller.rb」ファイルを以下のように編集します。
修正したは28行目、「create()」メソッドの「@line_item = @cart.add_good(good)」の部分です。


記述追加 【SampleCart/app/controllers/line_items_controller.rb】

class LineItemsController < ApplicationController

  include CurrentCart
	before_action :set_cart, only: [:create]
  before_action :set_line_item, only: %i[ show edit update destroy ]

  # GET /line_items or /line_items.json
  def index
    @line_items = LineItem.all
  end

  # GET /line_items/1 or /line_items/1.json
  def show
  end

  # GET /line_items/new
  def new
    @line_item = LineItem.new
  end

  # GET /line_items/1/edit
  def edit
  end

  # POST /line_items or /line_items.json
  def create
    good = Good.find(params[:good_id])
    @line_item = @cart.add_good(good)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to line_item_url(@line_item), notice: "商品をカートに追加しました。" }
        format.json { render :show, status: :created, location: @line_item }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /line_items/1 or /line_items/1.json
  def update
    respond_to do |format|
      if @line_item.update(line_item_params)
        format.html { redirect_to line_item_url(@line_item), notice: "Line item was successfully updated." }
        format.json { render :show, status: :ok, location: @line_item }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /line_items/1 or /line_items/1.json
  def destroy
    @line_item.destroy!

    respond_to do |format|
      format.html { redirect_to line_items_url, notice: "Line item was successfully destroyed." }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_line_item
      @line_item = LineItem.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def line_item_params
      params.require(:line_item).permit(:good_id, :cart_id)
    end
end



カートの「show」ビューにも変更を加えます。
「SampleCart/app/views/carts」フォルダにある「show.html.erb」ファイルを以下のように編集します。
9行目に<%= item.quantity %>の記述を追加しています。


記述編集 【SampleCart/app/views/carts/show.html.erb】9行目

<p style="color: green"><%= notice %></p>

<div class="container">
  <div class="card">
    <div class="card-body">
      <div class="card-title h5"><strong>現在のカート</strong></div>
      <% @cart.line_items.each do |item| %>
        <div>
          <%= item.good.title %> × <%= item.quantity %>
        </div>
      <% end %>
      <div class="mt-4">
        <%= link_to "カートの編集", edit_cart_path(@cart), class: "btn btn-warning" %>
        <%= link_to "戻る", carts_path, class: "btn btn-secondary" %>
      </div>
      <div class="mt-4">
        <%= button_to "カートを削除", @cart, method: :delete, class: "btn btn-danger" %>
      </div>

    </div>
  </div>
</div>



ブラウザを確認します。
複数の商品をカートに入れて確認して下さい。
http://localhost:3000/carts/1

カートに数量追加
カートに数量追加




14 | セッションカートの実装】 << 【ホーム】 >> 【16 | エラー処理





↓↓クリックして頂けると励みになります。