Pt-E-4
Here is my solution I was kinda hoping to get it to redirect to the cart but I didn’t get it working as I wanted and ended up redirecting back to the catalog and leaving a notice
Show.html.erb
<div class="cart_title">Your Cart</div>
<table>
<% for item in @cart.line_items %>
<tr>
<td><%= item.quantity %>×</td>
<td><%= item.product.title %></td>
<td class="item_price"><%= number_to_currency(item.total_price) %></td>
<td><%= button_to 'Delete Line Item', item, :method => :delete, :confirm => 'Are You Sure' %></td>
</tr>
<% end %>
<tr class="total_line">
<td colspan="2">Total</td>
<td class="total_cell"><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>
<%= button_to 'Empty cart', @cart, :method => :delete,
:confirm => 'Are you sure?' %>
line_items_controller.rb
def destroy
@line_item = LineItem.find(params[:id])
@line_item.destroy
respond_to do |format|
format.html { redirect_to(store_url, :notice => 'Line Item Removed' )}
format.xml { head :ok }
end
end
Redirecting to Cart
In order to get it to redirect to cart, I used the following code. But with this code, I couldn’t get it to post a notice. Any ideas?
line_items_controller.rb
def destroy
@line_item = LineItem.find(params[:id])
@line_item.destroy
respond_to do |format|
format.html { redirect_to(@line_item.cart, :notice => 'Item has been removed from your cart.') }
format.xml { head :ok }
end
end
notice in view
Make sure that your view is setup to display your notice on the cart page. i.e.
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
Diogo Says
I went a bit further and added a condition to redirect to the store if the cart is empty.
line_items_controller.rb
def destroy
@line_item = LineItem.find(params[:id])
@line_item.destroy
respond_to do |format|
if current_cart.line_items.empty?
format.html { redirect_to(store_url, :notice=> 'Your cart is empty') }
else
format.html { redirect_to(current_cart, :notice=> 'Item Removed') }
end
format.xml { head :ok }
end
end
Doc says
I took the route of decrementing the quantity of each line item before destroying it.
File: app/controllers/carts_controller.rb (return to the store once cart is empty)
...
def show
begin
@cart = Cart.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to store_url, :notice => 'Invalid cart'
else
if @cart.line_items.count.zero?
respond_to do |format|
format.html { redirect_to(store_url,
:notice => 'Your cart is currently empty') }
format.xml { head :ok }
end
else
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @cart }
end
end
end
end
...
File: app/controllers/line_items_controller.rb (decrement quantity of line item until it reaches 1 before destroying it; return to cart)
...
def destroy
@line_item = LineItem.find(params[:id])
if @line_item.quantity > 1
@line_item.update_attributes(:quantity => @line_item.quantity - 1)
else
@line_item.destroy
end
respond_to do |format|
format.html { redirect_to(cart_url(session[:cart_id])) }
format.xml { head :ok }
end
end
...
File: app/views/carts/show.html.erb (modify Back link to go to store main page, provide Remove link for each line item; return to cart)
...
<% for item in @cart.line_items %>
<tr>
<td><%= item.quantity %>×</td>
<td><%= item.product.title %></td>
<td class="item_price">
<%= number_to_currency(item.total_price) %>
</td>
<td><%= link_to 'Remove', item, :method => :delete %></td>
</tr>
<% end %>
...
<%= link_to 'Back', store_path %>
...
Menachem says: I went one step further and allowed the user to change the quantity to any amount he wants; changing the quantity to 0 causes the item to be deleted
Show.html.erb
<div class="cart_title" >Your Cart</div>
<table>
<% for item in @cart.line_items %>
<% form_for item do |f|%>
<tr>
<td>
<%= f.submit :value => "Update Qty" %>
<%= f.text_field :quantity, :size => 1 %>
</td>
<td><%= item.product.title %></td>
<td class="item_price" ><%= number_to_currency(item.total_price) %></td>
</tr>
<% end %>
<% end %>
<tr class="total_line" >
<td colspan="2" >Total</td>
...
line_items_controller.rb
def update
@line_item = LineItem.find(params[:id])
respond_to do |format|
if @line_item.update_attributes(params[:line_item])
if (@line_item.quantity == 0)
@line_item.destroy
end
format.html { redirect_to(@line_item.cart) }
format.xml { head :ok }
...
Functional Test for Removing Line Item
So I took the approach of redirecting to the cart (empty or not) after the line item is removed.
format.html { redirect_to(@line_item.cart, :notice => 'Removed item') }
when I update the corresponding functional test with:
assert_redirected_to cart_path
I get
test_should_destroy_line_item(LineItemsControllerTest): ActionController::ActionControllerError: Cannot redirect to nil!
boldHas anyone found a workable solution to this yet?bold
Page History
- V32: Nish Lalgee [5 months ago]
- V31: Nish Lalgee [5 months ago]
- V47: Alexander Bradley [about 6 years ago]
- V31: lulalala [almost 7 years ago]
- V30: lulalala [almost 7 years ago]
- V29: Christopher Paul [almost 7 years ago]
- V28: Christopher Paul [almost 7 years ago]
- V27: ubique [about 7 years ago]
- V26: ubique [about 7 years ago]
- V25: ubique [about 7 years ago]