Ruby on Rails カート内の項目の数量を減らす
Rails によるアジャイルWebアプリケーション開発 第3版 の『第9章 タスク D : Ajax の追加』の自由課題『カート内の項目の数量を減らす方法』について。
まず、Ajax を使わずにカートの商品を減らすボタンを実装する。
これは、以下の4つの手順で行なっていく。
- ビューのカートの商品部分に削除ボタンを追加する
- コントローラに
delete_from_cart
メソッドを追加する - カートモデルに
delete_product
メソッドを追加する - アイテムモデルに
decrement_quantity
メソッドを追加する
削除ボタンの追加
app/views/store/_cart_item.html.erb に button_to
で削除ボタンを追加する。
このボタンでコントローラに delete_from_cart
メソッドを実行させる。
また、引数としてアイテムの id
を渡す。
ボタンのラベルは『-
』にしておく。
<% item_tr_if(cart_item == @current_item, cart_item.quantity) do %> <td><%= cart_item.quantity %> × </td> <td><%=h cart_item.title %></td> <td class="item-price"><%= number_to_currency(cart_item.price) %></td> <td><%= button_to "-", :action => "delete_from_cart", :id => cart_item.product %></td> <% end %>
コントローラに削除メソッドを追加
app/controllers/store_controller.rb に削除メソッド delete_from_cart
を追加する。
引数として渡された id
から商品を特定し、カートモデルに商品の削除をさせる。
実行後はリダイレクトしてページの更新をする。
def delete_from_cart product = Product.find(params[:id]) @cart = find_cart @cart.delete_product(product) redirect_to_index end
カートモデルから商品を削除
app/models/cart.rb に商品削除の delete_product
メソッドを追加する。
コントローラから呼び出された delete_product
メソッドは、引数として渡された product
から一致するカートアイテムを探し出し、その個数を 1
減少させる。
減少させた後の個数が 0
ならばカートからアイテムを削除しておく。
def delete_product(product) current_item = @items.find {|item| item.product == product } if current_item.decrement_quantity == 0 @items.delete(current_item) end current_item end
カートの商品情報の個数を減少させる
カートの商品情報モデル CartItem
の @quantity
を 1
減少させるメソッド decrement_quantity
を追加する。
def decrement_quantity @quantity -= 1 end
以上で、Ajax を使わない通常の HTML の商品削除処理が追加できた。
続いて、このコードに Ajax を使った処理を追加していく。
Ajax 処理の追加で行うことは以下の3つ。
- 削除ボタンを Ajax 対応に変更
delete_from_cart
メソッドを Ajax リクエストを受け取るように変更- レスポンスとして返す JavaScript を作る
削除ボタンの Ajax 対応化
app/views/store/_cart_item.html.erb の削除フォームボタンを Ajax 対応化させる。
<% item_tr_if(cart_item == @current_item, cart_item.quantity) do %> <td><%= cart_item.quantity %> × </td> <td><%=h cart_item.title %></td> <td class="item-price"><%= number_to_currency(cart_item.price) %></td> <td> <% form_remote_tag :url => { :action => "delete_from_cart", :id => cart_item.product } do %> <%= submit_tag "-" %> <% end %> </td> <% end %>
コントローラのメソッドを Ajax 対応化
app/controllers/store_controller.rb の delete_from_cart
メソッドを Ajax リクエストを受け取り Ajax レスポンスを返すように修正する。
def delete_from_cart product = Product.find(params[:id]) @cart = find_cart @cart.delete_product(product) respond_to do |format| format.js if request.xhr? format.html { redirect_to_index } end end
Ajax レスポンスの作成
コントローラが Ajax リクエストを受け取った時にレスポンスとして返すことになる JavaScript を作る RJS テンプレートを作成する。
app/views/store/delete_from_cart.js.rjs にカート項目の削除後にレンダリングすることになる HTML を作らせる。
さらに、カートの中身が空になった際にカートを blind_up
効果で非表示にさせる処理も加える。
各アイテムの個数が 0
個になった場合に視覚効果を使って画面上から消そうと思ったが、簡単にできそうにないので断念した。
page.replace_html("cart", :partial => "cart", :object => @cart) page[:cart].visual_effect :blind_up if @cart.total_items == 0
以上で Ajax を使ったカート項目の削除処理が完成した。
オーム社
売り上げランキング: 29946