Ruby on rails 问题的STI和form_
我使用单表继承来管理不同类型的项目 型号:Ruby on rails 问题的STI和form_,ruby-on-rails,form-for,sti,Ruby On Rails,Form For,Sti,我使用单表继承来管理不同类型的项目 型号: class Project < ActiveRecord::Base end class SiteDesign < Project end class TechDesign < Project end 查看edit.html.erb: <% form_for(@project, :url => {:controller => "projects",:action => "update"}) do |f|
class Project < ActiveRecord::Base
end
class SiteDesign < Project
end
class TechDesign < Project
end
查看edit.html.erb:
<% form_for(@project, :url => {:controller => "projects",:action => "update"}) do |f| %>
...
<%= submit_tag 'Update' %>
<% 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.[]
在参数中,很明显,我使用的不是项目参数名称,而是技术设计
参数:
{"commit"=>"Update",
"_method"=>"put",
"authenticity_token"=>"pd9Mf7VBw+dv9MGWphe6BYwGDRJHEJ1x0RrG9hzirs8=",
"id"=>"15",
"tech_design"=>{"name"=>"ech",
"concept"=>"efds",
"type"=>"TechDesign",
"client_id"=>"41",
"description"=>"tech"}}
<% form_for(@project, as: :project, url: {controller: :projects, action: :update}) do |f| %>
...
<% end %>
如何修复它?这是问题的根源。这是将@project设置为TechDesign对象的实例
def edit
@project = Project.find(params[:id])
end
您可以通过指定:project作为形式为_forcall的名称来确保事情按您想要的方式进行
<% form_for(:project, @project, :url => {:controller => "projects",:action => "update"}) do |f| %>
...
<%= submit_tag 'Update' %>
<% end %>
{:controller=>“projects”,:action=>“update”})do | f |%>
...
随机提示:如果您使用单表继承(STI)并忘记从子类定义中删除initialize方法,您将得到类似的“nil object when you not expected”异常
例如:
class Parent < ActiveRecord::Base
end
class Child < Parent
def initialize
# you MUST call *super* here or get rid of the initialize block
end
end
类父级
在我的例子中,我使用IDE创建子类,IDE创建了initialize方法。我花了很长时间才找到Rails 3的…
<% form_for(@project, :as => :project, :url => {:controller => "projects",:action => "update"}) do |f| %>
...
<%= submit_tag 'Update' %>
<% end %>
:project,:url=>{:controller=>“projects”,:action=>“update”})do | f |%>
...
对于Rails 4,我已经确认唯一对我有效的方法是显式指定URL和AS参数:
{"commit"=>"Update",
"_method"=>"put",
"authenticity_token"=>"pd9Mf7VBw+dv9MGWphe6BYwGDRJHEJ1x0RrG9hzirs8=",
"id"=>"15",
"tech_design"=>{"name"=>"ech",
"concept"=>"efds",
"type"=>"TechDesign",
"client_id"=>"41",
"description"=>"tech"}}
<% form_for(@project, as: :project, url: {controller: :projects, action: :update}) do |f| %>
...
<% end %>
...
我觉得很难看 谢谢你的回复。在这些更改之后,我得到了这个错误:1没有响应任何操作。操作:添加此映射后创建、销毁、编辑、索引、新建、显示和更新。连接“projects/:id/edit”、:controller=>“projects”、:action=>“edit”到routes.rb错误已消除。问题是,如果map.resources:projects已经出现在routes中,为什么没有它就不能工作呢?在Rails 3.1中,将语句的形式_写为:project do | f |%>旧线程,但因为我在谷歌搜索时发现了它,所以我就是这么做的:注意,
:as=>:project
只会影响参数,而不会影响URL。