131216_02:アジャイル開発本

10.3 イテレーション E3:カートの仕上げ

カートを空にする機能を実装する。

カートを空にする機能を実装するには、カートにリンクを追加し、カートコントローラのdestroy( )メソッドを修正してセッションをクリーンアップしなけらばならない。まずテンプレートの作業から始める。ここでもbutton_to( )メソッドを使ってページにボタンを配置する。

 

app/views/carts/show.html.erbに

<%= button_to 'カートを空にする', @cart, method: :delete,

confirm: '本当に良いですか?' %>

を追加。

 

コントローラではdestroy( )を修正。ユーザの同意を得てカートを削除し、セッションからカートを削除したうえで、通知メッセージ付きのインデックスページにリダイレクトするようにする。

app/controllers/carts_controller.rbを編集

  # DELETE /carts/1

  # DELETE /carts/1.json

  def destroy

    @cart = current_cart

    @cart.destroy

    session[:cart_id] = nil

 

    respond_to do |format|

      format.html { redirect_to store_url,

        notice: 'カートは現在空です' }

      format.json { head :ok }

    end

  end

さらに対応するテストも更新する。

test/functional/carts_controller_test.rb

  test "should destroy cart" do

    assert_difference('Cart.count', -1) do

      delete :destroy, {id: @cart.to_param}, {cart_id: @cart.id}

    end

 

    assert_redirected_to store_path

  end

end

 

最後にカートの表示を整える。各項目に<li>エレメントを使わず、表を使うようにしましょう。ここもCSSでスタイリングする。

app/views/carts/show.html.erbを編集する。

<% if notice %>

<p id="notice"><%= notice %></p>

<% end %>

 

<div class="cart_title">カート</div>

<table>

  <% @cart.line_items.each do |item| %>

    <tr>

      <td><%= item.quantity %>&times;</td>

      <td><%= item.product.title %></td>

      <td class="item_price"><%= number_to_currency(item.total_price) %></td>

    </tr>

  <% end %>

 

  <tr class="total_line">

    <td colspan="2">合計</td>

    <td class="total_cell"><%= number_to_currency(@cart.total_price) %></td>

  </tr>

 

</table>

 

<%= button_to 'カートを空にする', @cart, method: :delete,

    confirm: '本当によいですか?' %>

 

この作業では、各品目の合計価格を返すメソッドをLineItemモデルに、カート全体の合計価格を返すメソッドをCartモデルに、それぞれ追加する必要がある。まずは品目の合計価格。

app/models/line_item.rbを編集。

class LineItem < ActiveRecord::Base

  belongs_to :product

  belongs_to :cart

 

  def total_price

  product.price * quantity

  end

end

 

次はカート全体の合計価格。Cartに実装するこのメソッドでは、コレクション内の各項目の価格を合計するのに、Railsの便利なメソッドArray#sum( )を使う。

app/models/cart.rbを編集。

class Cart < ActiveRecord::Base

  has_many :line_items, dependent: :destroy

 

  def add_product(product_id)

    current_item = line_items.find_by_product_id(product_id)

    if current_item

      current_item.quantity += 1

    else

      current_item = line_items.build(product_id: product_id)

    end

    current_item

  end

 

  def total_price

    line_items.to_a.sum { |item| item.total_price }

  end

end

 

次に、carts.css.scssスタイルシートに追加。

app/assets/stylesheets/carts.css.scss

 

この章のまとめ

  • 既存のテーブル二列を追加し、デフォルト値も指定
  • マイグレーションで既存のデータを新しいフォーマットのテーブルに行こう
  • 検出したエラーを通知するフラッシュメッセージを追加
  • loggerを使ってイベントログを記録した
  • レコードを削除した
  • CSSを使って表の見栄えを整えた