↓↓クリックして頂けると励みになります。
【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 | エラー処理】
↓↓クリックして頂けると励みになります。