【问题标题】:STI and form_for problemSTI 和 form_for 问题
【发布时间】:2009-10-16 15:04:05
【问题描述】:

我正在使用单表继承来管理不同类型的项目。

型号:

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

在参数中,很明显我有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"}}

如何解决?

【问题讨论】:

    标签: ruby-on-rails form-for sti


    【解决方案1】:

    这是您的问题的根源。这是将 @project 设置为 TechDesign 对象的实例。

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

    您可以通过在 form_for 调用中为名称指定 :project 来确保事情按照您想要的方式进行。

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

    【讨论】:

    • 感谢您的回复。在这些 chages 之后,我得到了这个错误:没有对 1 做出响应的操作。操作:创建、销毁、编辑、索引、新建、显示和更新
    • 添加此 map.connect "projects/:id/edit", :controller => "projects", :action => "edit" 到 routes.rb 后,错误消失了。问题是,如果 map.resources :projects 已经出现在路线中,为什么没有它就不能工作?
    • 在 Rails 3.1 中,将 form_for 语句写成 :project do |f| %>
    • 老线程,但因为我在谷歌搜索时发现它,所以我这样做了:henrik.nyh.se/2012/08/rails-sti-and-form-for 注意:as =&gt; :project 只会影响参数,而不是 URL。
    【解决方案2】:

    适用于 Rails 3

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

    【讨论】:

      【解决方案3】:

      随机说明:如果您使用单表继承 (STI) 并忘记从子类定义中删除 initialize 方法,您将在没想到时得到类似的“nil 对象” " 例外。

      例如:

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

      【讨论】:

        【解决方案4】:

        对于 Rails 4,我已经确认唯一似乎对我有用的是明确指定 URL 和 AS 参数:

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

        我觉得很丑!

        【讨论】:

          猜你喜欢
          • 2023-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-03
          相关资源
          最近更新 更多