想必很多人都看过Web开发敏捷之道--应用Rails进行敏捷Web开发(第2版),我试着运行了改书中的checkout功能,却有以下错误产生。
引用
NoMethodError in Store#checkout
Showing app/views/layouts/store.rhtml where line #22 raised:
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.items
Extracted source (around line #22):
19: <div id="columns">
20: <div id="side">
21: <% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
22: <%= render(:partial => "cart",
bject => @cart) %>
23: <% end %>
24:
25:
要说明的是,之前的功能包括向购物车中添加物品(Ajax),清除购物车的物品都完全正常,在网上寻求资料也没有找到。
还有 我使用的是netbeans6.0自带的ruby和rails版本
下面是我的一些代码:
store_controller.rb
class StoreController < ApplicationController
def index
@products = Product.find_products_for_sale
@cart = find_cart
end
def add_to_cart
begin
product = Product.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}")
redirect_to_index("Invalid product")
else
@cart = find_cart
@current_item = @cart.add_product(product)
redirect_to_index unless request.xhr?
end
end
def empty_cart
session[:cart] = nil
redirect_to :action => :index
end
private
def find_cart
session[:cart] ||= Cart.new
end
def redirect_to_index(msg = nil)
flash[:notice] = msg if msg
redirect_to :action => :index
end
def checkout
@cart = find_cart
if @cart.items.empty?
redirect_to_index("Your cart is empty")
else
@order = Order.new
end
end
def save_order
@cart = find_cart
@order = Order.new(params[:order])
@order.add_line_items_from_cart(@cart)
if @order.save
session[:cart] = nil
redirect_to_index("Thank you for your order")
else
render :action => :checkout
end
end
end
checkout.rhtml
<!--
! Excerpted from "Agile Web Development with Rails, 2nd Ed."
! We make no guarantees that this code is fit for any purpose.
! Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
-->
<div class="depot-form">
<%= error_messages_for(:order) if @order %>
<fieldset>
<legend>Please Enter Your Details</legend>
<% form_for :order, :url => { :action => :save_order } do |form| %>
<p>
<label for="order_name">Name:</label>
<%= form.text_field :name, :size => 40 %>
</p>
<p>
<label for="order_address">Address:</label>
<%= form.text_area :address, :rows => 3, :cols => 40 %>
</p>
<p>
<label for="order_email">E-Mail:</label>
<%= form.text_field :email, :size => 40 %>
</p>
<p>
<label for="order_pay_type">Pay with:</label>
<%=
form.select :pay_type,
Order::PAYMENT_TYPES,
:prompt => "Select a payment method"
%>
</p>
<%= submit_tag "Place Order", :class => "submit" %>
<% end %>
</fieldset>
</div>
views/layouts下的store.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
! Excerpted from "Agile Web Development with Rails, 2nd Ed."
! We make no guarantees that this code is fit for any purpose.
! Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
-->
<html>
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot", :media => "all" %>
<%= javascript_include_tag :defaults %>
</head>
<body id="store">
<div id="banner">
<%= image_tag("logo.png") %>
<%= @page_title || "Pragmatic Bookshelf" %>
</div>
<div id="columns">
<div id="side">
<% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
<%= render(:partial => "cart", :object => @cart) %>
<% end %>
<a href="http://www....">Home</a><br />
<a href="http://www..../faq">Questions</a><br />
<a href="http://www..../news">News</a><br />
<a href="http://www..../contact">Contact</a><br />
</div>
<div id="main">
<% if flash[:notice] -%>
<div id="notice"><%= flash[:notice] %></div>
<% end -%>
<%= yield :layout %>
</div>
</div>
</body>
</html>
Helpers下的store_helper.rh
module StoreHelper
def hidden_div_if(condition, attributes = {}, &block)
if condition
attributes["style"] = "display: none"
end
content_tag("div", attributes, &block)
end
end