我目前正在进行“使用Rails进行敏捷Web开发 - 第4版”,我被困住了。 结账按钮应该会显示订单页面,但我得到此错误:
NoMethodError in Orders#new
Showing C:/Sites/depot/app/views/orders/_form.html.erb where line #1 raised:
undefined method `model_name' for NilClass:Class
Extracted source (around line #1):
1: <%= form_for(@order) do |f| %>
2: <% if @order.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(@order.errors.count, "error") %>
在花了很多时间试图解决这个问题之后,我复制了书籍网站上的所有源代码,但仍无效。我甚至检查了勘误表和书籍论坛,一无所获。
我做错了什么?
这是来自views / orders / _form.html.erb的代码:
<%= form_for(@order) do |f| %>
<% if @order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@order.errors.count, "error") %>
prohibited this order from being saved:</h2>
<ul>
<% @order.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<!-- START_HIGHLIGHT -->
<%= f.text_field :name, size: 40 %>
<!-- END_HIGHLIGHT -->
</div>
<div class="field">
<%= f.label :address %><br />
<!-- START_HIGHLIGHT -->
<%= f.text_area :address, rows: 3, cols: 40 %>
<!-- END_HIGHLIGHT -->
</div>
<div class="field">
<%= f.label :email %><br />
<!-- START_HIGHLIGHT -->
<%= f.email_field :email, size: 40 %>
<!-- END_HIGHLIGHT -->
</div>
<div class="field">
<%= f.label :pay_type %><br />
<!-- START_HIGHLIGHT -->
<%= f.select :pay_type, Order::PAYMENT_TYPES,
prompt: 'Select a payment method' %>
<!-- END_HIGHLIGHT -->
</div>
<div class="actions">
<!-- START_HIGHLIGHT -->
<%= f.submit 'Place Order' %>
<!-- END_HIGHLIGHT -->
</div>
<% end %>
这是订单控制器:
class OrdersController < ApplicationController
def index
@orders = Order.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @orders }
end
end
# GET /orders/1
# GET /orders/1.json
def show
@order = Order.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @order }
end
end
# GET /orders/new
# GET /orders/new.json
def new
@cart = current_cart
if @cart.line_items.empty?
redirect_to store_url, notice: "Your cart is empty"
return
end
@order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @order }
end
end
# GET /orders/1/edit
def edit
@order = Order.find(params[:id])
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(params[:order])
@order.add_line_items_from_cart(current_cart)
respond_to do |format|
if @order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to store_url, notice:
'Thank you for your order.' }
format.json { render json: @order, status: :created,
location: @order }
else
@cart = current_cart
format.html { render action: "new" }
format.json { render json: @order.errors,
status: :unprocessable_entity }
end
end
end
# PUT /orders/1
# PUT /orders/1.json
def update
@order = Order.find(params[:id])
respond_to do |format|
if @order.update_attributes(params[:order])
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
@order = Order.find(params[:id])
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :ok }
end
end
end
这是订单型号:
class Order < ActiveRecord::Base
PAYMENT_TYPES = [ "Check", "Credit card", "Purchase order" ]
has_many :line_items, dependent: :destroy
# ...
validates :name, :address, :email, presence: true
validates :pay_type, inclusion: PAYMENT_TYPES
end
答案 0 :(得分:0)
form
视图认为此处@order
为nil
:
1: <%= form_for(@order) do |f| %>
您在浏览器中遇到的路径是什么? /orders/new
看来Order#new
似乎将@order
设置为Order.new
,所以我想知道你是否真的在击中那个控制器。
Rails会根据routes.rb
中设置的内容将请求路由到控制器操作。运行rake routes
以查看您可以在网址中访问的路由。
Rails有一些约定,如果您使用简单的GET请求访问/orders/new
,它会将您的请求路由到new
的{{1}}操作,并会尝试呈现关联OrdersController
- 除非您自定义此内容的某些方面。
我会在app/views/orders/new.html.erb
分配后的puts "Order is set to: #{@order}"
操作中添加new
,以确保它实际上正在通过该路径。