在Rails中提交嵌套表单时出现500内部服务器错误

时间:2014-01-12 13:34:32

标签: ruby-on-rails ruby ruby-on-rails-3 forms internal-server-error

当我提交具有两个模型的嵌套表单时,我收到500内部服务器错误 - Member和ChildrenInformation。

错误:

  

500内部服务器错误

     

如果您是本网站的管理员,请阅读此Web应用程序的日志文件和/或Web服务器的日志文件,以了解出现了什么问题。

我检查了日志文件,这是我发现的:

  

TypeError(param`child_info_attrib'的预期Hash(获取数组)):   

以下是我的铁路项目的其他部分

查看(new.html.erb>

  <%= form_for(@member) do |f| %>
 <div class="field">
    <%= f.label :gender, "Gender" %><br />
    <%= f.select :gender, options_for_select(["Male", "Female"]) %>
  </div>
 <div class="field">
    <%= f.label :fname, "First Name" %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :age, "Age" %><br />
    <%= f.text_field :age %>
  </div>
   <div class="field">
    <%= f.label :membership_id, "Membership ID" %>
    <%= f.text_field :membership_id %>
  </div>
  <div class="field">
    <%= f.label "Branch" %>
    <%= f.collection_select(:branch_id, Branch.all, :id, :name) %>
  </div>
  <% for children_information in @member.children_informations %>
     <%= fields_for "member[child_info_attrib][]", children_information do |children_info_form| %>
      <div class="field">
        <%= children_info_form.label :name, "Name" %><br />
        <%= children_info_form.text_field :name %>
      </div>
      <div class="field">
        <%= children_info_form.label :gender, "Gender" %><br />
        <%= children_info_form.select :gender, options_for_select(["Male", "Female"]) %>
      </div>
      <div class="field">
        <%= children_info_form.label :birthdate, "Birthdate" %><br />
     nn <%= children_info_form.datetime_select :birthdate, :discard_hour => true, 
:order => [:month, :day, :year], :start_year => 1900 %>
        </div>
   </div>
       <% end %>
    <% end %>`

模特(会员)

 class Member < ActiveRecord::Base
    has_many :children_informations

    def child_info_attrib=(attribs)
        attribs.each do |attrib|
          children_informations.build(attrib)
        end
    end 
 end

模型(儿童信息)

class ChildrenInformation < ActiveRecord::Base
    belongs_to :member
end

控制器(MembersController)

class MembersController < ApplicationController
def new
    @member = Member.new
    @member.children_informations.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @member }
    end
  end
def create
    @member = Member.new(params[:member])
    respond_to do |format|
      if @member.save
        format.html { redirect_to(@member, :notice => 'Member was successfully created.') }
        format.xml  { render :xml => @member, :status => :created, :location => @member }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @member.errors, :status => :unprocessable_entity }
      end
    end
  end

开发日志: http://pastebin.com/n9E2nyFv(会员表有很多字段)

到目前为止我尝试的是省略嵌套表单,它确实有效。
另外,我基于这种通过RailsCasts(http://railscasts.com/episodes/73-complex-forms-part-1)使用嵌套表单的方式。

如何使用嵌套表单成功提交?

提前谢谢! :)

3 个答案:

答案 0 :(得分:4)

我认为您正在错误地构建嵌套表单:

#app/views/members/new.html.erb
 <% for children_information in @member.children_informations %>
     <%= fields_for "member[child_info_attrib][]", children_information do |children_info_form| %>
      <div class="field">
        <%= children_info_form.label :name, "Name" %><br />
        <%= children_info_form.text_field :name %>
      </div>
      <div class="field">
        <%= children_info_form.label :gender, "Gender" %><br />
        <%= children_info_form.select :gender, options_for_select(["Male", "Female"]) %>
      </div>
      <div class="field">
        <%= children_info_form.label :birthdate, "Birthdate" %><br />
     nn <%= children_info_form.datetime_select :birthdate, :discard_hour => true, 
:order => [:month, :day, :year], :start_year => 1900 %>
        </div>
   </div>
       <% end %>
  <% end %>

你需要这样做:

查看

<%= f.fields_for :children_informations do |children_info_form| %>
      <div class="field">
        <%= children_info_form.label :name, "Name" %><br />
        <%= children_info_form.text_field :name %>
      </div>
      <div class="field">
        <%= children_info_form.label :gender, "Gender" %><br />
        <%= children_info_form.select :gender, options_for_select(["Male", "Female"]) %>
      </div>
      <div class="field">
        <%= children_info_form.label :birthdate, "Birthdate" %><br />
     nn <%= children_info_form.datetime_select :birthdate, :discard_hour => true, 
:order => [:month, :day, :year], :start_year => 1900 %>
        </div>
   </div>
<% end %>

这将创建具有正确数据的表单元素,但我也认为您可以改进对数据的处理。当你在Rails 3上时,我会等待评论,看看你是否希望我为它写一些代码!

答案 1 :(得分:1)

您关注的轨道广播剧集的日期是2007年。 我不认为这种方法在嵌套表单中是最好的。

def child_info_attrib=(attribs)
    attribs.each do |attrib|
      children_informations.build(attrib)
    end
end

可以简化为此(如果您使用的是rails 3.x&gt;)

  

attr_accessible:childs_attributes
  accepts_nested_attributes_for:childs

如果你想要参考或一些教程,我会建议你 http://railscasts.com/episodes/196-nested-model-form-revised
http://railscasts.com/episodes/197-nested-model-form-part-2

或者如果你不这些,你可以看看这个宝石 https://github.com/nathanvda/cocoon
这简化了你想要实现的目标。

答案 2 :(得分:0)

这是一个错误,我破坏了关于嵌套表单(http://railscasts.com/episodes/73-complex-forms-part-1)的RailsCasts剧集的注释,它已经过时了,我应该按照上述主题的最新一集(http://railscasts.com/episodes/196-nested-model-form-part-1)。它现在有效:)