Railsの勉強1

RailsによるアジャイルWebアプリケーション開発 第2版 P122の自由課題。

カート内の各項目の隣にリンクを追加しましょう。これをクリックすると商品の数量を減らすアクションが呼び出され、数量が0になるとカートからその項目が削除されるように設定してみましょう。

_cart_item.rhtml に以下を追加。

<td><%= link_to_remote "削除", :url => { :action => :remove_from_cart , :id => cart_item.product} %></td>

remove_from_cart.rjs を作成。

page.replace_html("cart", :partial => "cart", :object => @cart)
page[:cart].visual_effect :blind_up if @cart.total_items == 0

次にコントローラ。store_controller.rbに以下を定義。

def remove_from_cart
  begin
    product = Product.find( params[:id] )
  rescue
    logger.error("無効な商品 #{params[:id]} にアクセスしようとしました")
    redirect_to_index( "無効な商品です" )
  else
    @cart = find_cart
    @current_item = @cart.remove_product( product )
    redirect_to_index unless request.xhr?
  end
end

モデルをいじる。cart.rbに以下を定義。

def remove_product(product)
  current_item = @items.find {|item| item.product == product}
  current_item.decrement_quantity
  if current_item.quantity == 0
    @items.delete( current_item )
  end
  current_item
end

cart_item.rbに以下を定義。

def decrement_quantity
  @quantity -= 1 if @quantity > 0
end

ここまでで動作確認。動いたら、コントローラの冗長部分を切り出してDRYっぽくする。

def manage_cart
  begin
    product = Product.find( params[:id] )
  rescue
    logger.error("無効な商品 #{params[:id]} にアクセスしようとしました")
    redirect_to_index( "無効な商品です" )
  else
    @cart = find_cart
    @current_item = yield product
    redirect_to_index unless request.xhr?
  end
end

def add_to_cart
  manage_cart {|product| @cart.add_product( product )}
end

def remove_from_cart
  manage_cart {|product| @cart.remove_product( product )}
end

以上。RJSではまるとデバッグが大変です。

RailsによるアジャイルWebアプリケーション開発 第2版

RailsによるアジャイルWebアプリケーション開発 第2版