STI 和 form_for 问题
我正在使用单表继承来管理不同类型的项目。
模型:
class Project < ActiveRecord::Base
end
class SiteDesign < Project
end
class TechDesign < Project
end
从projects_controller编辑操作:
def edit
@project = Project.find(params[:id])
end
查看edit.html.erb:
<% form_for(@project, :url => {:controller => "projects",:action => "update"}) do |f| %>
...
<%= submit_tag 'Update' %>
<% end %>
更新projects_controller的操作:
def update
@project = Project.find(params[:id])
respond_to do |format|
if @project.update_attributes(params[:project])
@project.type = params[:project][:type]
@project.save
flash[:notice] = 'Project was successfully updated.'
format.html { redirect_to(@project) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @project.errors, :status => :unprocessable_entity }
end
end
end
然后我在编辑视图上对TechDesign条目进行一些编辑并得到错误:
NoMethodError in ProjectsController#update
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
在parameters中,很明显,我有tech_design而不是项目参数名称 参数:
{"commit"=>"Update",
"_method"=>"put",
"authenticity_token"=>"pd9Mf7VBw+dv9MGWphe6BYwGDRJHEJ1x0RrG9hzirs8=",
"id"=>"15",
"tech_design"=>{"name"=>"ech",
"concept"=>"efds",
"type"=>"TechDesign",
"client_id"=>"41",
"description"=>"tech"}}
如何修复?
I am using Single Table Inheritance for managing different types of projects.
Models:
class Project < ActiveRecord::Base
end
class SiteDesign < Project
end
class TechDesign < Project
end
Edit action from projects_controller:
def edit
@project = Project.find(params[:id])
end
View edit.html.erb:
<% form_for(@project, :url => {:controller => "projects",:action => "update"}) do |f| %>
...
<%= submit_tag 'Update' %>
<% end %>
Update action of projects_controller:
def update
@project = Project.find(params[:id])
respond_to do |format|
if @project.update_attributes(params[:project])
@project.type = params[:project][:type]
@project.save
flash[:notice] = 'Project was successfully updated.'
format.html { redirect_to(@project) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @project.errors, :status => :unprocessable_entity }
end
end
end
Then i do some edits of TechDesign entry on edit view and get error:
NoMethodError in ProjectsController#update
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
In parametrs it is obvious that instead of project parameter name i have tech_design
Parameters:
{"commit"=>"Update",
"_method"=>"put",
"authenticity_token"=>"pd9Mf7VBw+dv9MGWphe6BYwGDRJHEJ1x0RrG9hzirs8=",
"id"=>"15",
"tech_design"=>{"name"=>"ech",
"concept"=>"efds",
"type"=>"TechDesign",
"client_id"=>"41",
"description"=>"tech"}}
How to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是你的问题的根源。这将 @project 设置为 TechDesign 对象的实例。
您可以通过在 form_for 调用中指定 :project 作为名称来确保事情按照您想要的方式工作。
Here's the source of your problem. This is setting @project as an instance of a TechDesign object.
You can ensure things work the way you want by specifying :project for a name in the form_for call.
对于 Rails 3
For Rails 3
随机提示:如果您使用单表继承 (STI) 并且忘记从子类定义中删除 initialize 方法,您将得到类似的“当您没有预料到时出现 nil 对象”异常。
例如:
在我的例子中,我使用 IDE 创建子类,并且 IDE 创建了初始化方法。我花了很长时间才找到...
A random note: If you are using single table inheritance (STI) and forget to remove the initialize method from your subclass definitions you will get a similar "nil object when you didn't expect it" exception.
For example:
In my case, I used my IDE to create the child classes and the IDE created the initialize method. Took me forever to track down...
对于 Rails 4,我已经确认唯一对我有用的方法是显式指定 URL 和 AS 参数:
对我来说似乎很难看!
For Rails 4, I have confirmed the only thing that has seemed to work for me is to explicitly specify the URL and the AS parameters:
Seems ugly to me!