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

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース

Ruby on RailsでWebアプリケーション開発その20 買い物カートに数量を追加

<<前  [TOP]  次>>


カートの商品に数量をつけるために「line_items」テーブルを修正します。
コマンドプロンプトで「shop」フォルダに移動し、「rails generate migration add_quantity_to_line_items quantity:integer」と入力して下さい。
f:id:MrRadiology:20180221122910p:plain
「int」型の「quantity」フィールドを作成するために「add_quantity_to_line_items.rb」という名前のファイルが「migrate」フォルダに作成されました。


作成された「add_quantity_to_line_items.rb」を編集して、「quantity」フィールドのデフォルト値が「1」になるようにします。


【db/migrate/add_quantity_to_line_items.rb】

class AddQuantityToLineItems < ActiveRecord::Migration
  def change
    add_column :line_items, :quantity, :integer, default: 1
  end
end

最後に「, default: 1」と追加しただけです。


では「rake db:migrate」コマンドでマイグレーションを実行します。
f:id:MrRadiology:20180221135709p:plain


「line_items」テーブルの内容を確認してみます。
f:id:MrRadiology:20180221135837p:plain


次に追加しようとしている商品がline_itemに含まれているかどうかを確認し、含まれていれば数量を増やし、含まれていなければ新たに作るという仕事をする「add_good()」メソッドを実装します。
「app/models」フォルダの「cart.rb」ファイルを以下のように編集します。


【app/models/cart.rb】

class Cart < ActiveRecord::Base

	has_many :line_items, dependent: :destroy

	def add_good(good_id)

		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

「find_by_good_id()」メソッドは何処にも定義していませんが、「find_by」で始まるメソッドの場合、Railsが自動でメソッドの作成とクラスへの追加を行ってくれます。
渡した「good_id」の商品を見つける仕事をしてくれます。


line_itemsコントローラの修正もあわせて行います。


【app/controllers/line_items_controller.rb】

class LineItemsController < ApplicationController
  before_action :set_line_item, only: [:show, :edit, :update, :destroy]

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

  # GET /line_items/1
  # GET /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
  # POST /line_items.json
  def create

	@cart = current_cart

	good = Good.find(params[:good_id])

	@line_item = @cart.add_good(good.id)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart, notice: 'カートに商品が追加されました。' }
        format.json { render :show, status: :created, location: @line_item }
      else
        format.html { render :new }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

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

  # DELETE /line_items/1
  # DELETE /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

    # Never trust parameters from the scary internet, only allow the white list through.
    def line_item_params
      params.require(:line_item).permit(:good_id, :cart_id)
    end
end

修正したのはcreate()メソッドの次の部分です。

@line_item = @cart.add_good(good.id)



showビューの変更も行います。


【app/views/carts/show.html.erb】

<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
<br>
<h1>Railsはじめてマート</h1>
<h2>   カートに追加された商品</h2>
<br>
<span>  </span><%= link_to '買い物を続ける', market_path, :class => 'btn' %><span>
<br>
<br>
<table>
	<tr>
		<th></th>
		<th>商品名</th>
		<th>価格</th>
		<th>数量</th>

	</tr>
		<% @cart.line_items.each do |item| %>
		<tr>
			<td text-align:center;><img height="80" src="<%=h item.good.image_url %>"/></td>
			<td text-align:center;><font size="4"><%= item.good.title %></font></td>
			<td text-align:center;><font size="4"><%= (item.good.price).to_i %></font></td>
			<td text-align:center;><font size="4"><%= item.quantity %></font></td>
		</tr>
		<% end %>

</table>



商品を何回かカートに入れて数量が増えるのを確認してみます。
f:id:MrRadiology:20180222122501p:plain


<<前  [TOP]  次>>