STI和的form_for问题(STI and form_for problem)

2019-08-19 05:36发布

我使用单表继承,用于管理不同类型的项目。

楷模:

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.[]

在parametrs很明显的,而不是项目参数名字我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"}}

如何解决呢?

Answer 1:

这是你的问题的根源。 这被设置@project作为TechDesign对象的实例。

def edit
   @project = Project.find(params[:id])
end

您可以确保工作的事情你想通过指定方式:项目中的form_for调用的名称。

<% form_for(:project, @project, :url => {:controller => "projects",:action => "update"}) do |f| %>
    ...
    <%= submit_tag 'Update' %>
<% end %>


Answer 2:

为Rails 3

<% form_for(@project, :as => :project, :url => {:controller => "projects",:action => "update"}) do |f| %>
...
   <%= submit_tag 'Update' %>
<% end %>


Answer 3:

随机注:如果您使用的是单表继承(STI),却忘了从子类的定义中删除初始化方法,你会得到一个类似的“无对象时,你没想到吧”异常。

例如:

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中创建初始化方法。 带我永远追查...



Answer 4:

对于轨道4,我已经证实,似乎已为我工作是明确指定的URL和作为参数的唯一的事情:

<% form_for(@project, as: :project, url: {controller: :projects, action: :update}) do |f| %>
    ...
<% end %>

似乎丑陋给我!



文章来源: STI and form_for problem