为什么我收到“No Method”错误?

时间:2013-07-23 17:34:12

标签: ruby ruby-on-rails-3.2

我目前正在进行“使用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

1 个答案:

答案 0 :(得分:0)

form视图认为此处@ordernil

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,以确保它实际上正在通过该路径。