两个控制器,一个型号 – 为什么我的应用程序正在寻找第二个型号?

我有一个订单模型。

客户可以获得一些消费者友好的视图,让他们创建和查看自己的订单,所有这些都由Orders控制器支持。

管理员可以获得全部视图,以便在购买控制器的支持下创建,编辑,查看,删除和管理订单。

据我所知,Purchases控制器应该只对Order模型说话,但是下面的错误信息让我觉得它正在寻找一个不存在的购买模型:

ActiveRecord::StatementInvalid in PurchasesController#new NameError in PurchasesController#new uninitialized constant Purchase Rails.root: /Users/steven/Dropbox/testivate 

这是错误的意思吗? 如果是,如何阻止Purchases控制器尝试查找购买模型?

我的代码……

应用程序/控制器/ purchases_controller.rb:

 class PurchasesController < ApplicationController def new @purchase = Order.new respond_to do |format| format.html # new.html.erb format.json { render json: @purchase } end end def create @purchase = Order.new(params[:purchase]) respond_to do |format| if @purchase.save format.html { redirect_to purchase_path(@purchase), notice: 'Purchase was successfully created.' } format.json { render json: @purchase, status: :created, location: @purchase } else format.html { render action: "new" } format.json { render json: @purchase.errors, status: :unprocessable_entity } end end end end 

/config/routes.rb:

 Testivate::Application.routes.draw do resources :orders resources :purchases end 

/app/views/purchases/new.html.haml:

 .textbox %p#notice= notice %h1 New Purchase = render 'form' = link_to 'List Purchases', purchases_path 

/app/views/purchases/_form.html.haml:

 = simple_form_for @purchase do |f| = f.error_notification = f.input :name = f.button :submit 

更新:所以我刚刚意识到’事务’是Rails中的保留字,所以我改变了。 但还有什么我需要解决的吗?

* 更新2:当我完全注释掉#new视图和_form时,我仍然会收到错误,所以我认为问题出在我的控制器或路由中,或者除了使用simple_form之外的其他地方。*

更新:

这是答案的一半。 对于另一半,请参阅有关该问题的评论。

原始答案:

这里的部分问题是,默认情况下, form_forsimple_form_for是在atop上构建)假设某些事物是关于给定记录使用哪些路径,它是从该记录的类派生的。 在你的情况下,因为@purchase实际上是Order类的一个实例,所以这些假设会为你搞砸。

如果你看一下simple_form_for生成的simple_form_for ,你会发现它给表单提供了一个id和一个new_order类,并且表单中的字段的名称类似于order[name] 。 要让rails在表单中使用purchase而不是order ,你必须传递一个:as选项。

来自form_for的文档 :

如果您有一个需要表示为不同参数的对象,例如充当客户端的Person:

他们提供的例子如下:

 <%= form_for(@person, :as => :client) do |f| %> ... <% end %> 

在您的情况下,您实际上想要告诉它将@purchase “购买”:

 = simple_form_for @purchase, :as => :purchase do |f| = f.error_notification = f.input :name = f.button :submit 

这将使表单ID等正确,这样您就可以在创建操作中使用例如params[:purchase] 。 但这还不够,因为表单的操作(URL)仍将最终成为/orders 。 要更改它,请添加:url选项:

 = simple_form_for @purchase, :as => :purchase, :url => purchases_path(@purchase) do |f| = f.error_notification = f.input :name = f.button :submit 

这也将解决您发布的其他问题 。