0

我目前正在阅读“使用 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
4

1 回答 1

0

form观点认为,这里@ordernil

1: <%= form_for(@order) do |f| %>

您在浏览器中点击的路径是什么?/orders/new

看起来确实Order#new设置@orderOrder.new,所以我想知道您是否真的在点击该控制器。

Rails 将根据routes.rb. 运行rake routes以查看您可以在 url 中访问的路由。

Rails 有这样的约定,如果您/orders/new使用简单的 GET 请求访问 ,它会将您的请求路由到 的new操作,OrdersController并尝试呈现关联的app/views/orders/new.html.erb- 除非您自定义它的某些方面。

我会在分配puts "Order is set to: #{@order}"后的new操作中添加一个,@order = Order.new以确保它实际上正在通过该路径。

于 2013-07-23T18:21:55.767 回答