Domanda

I get a 500 Internal Server Error when I submit the nested form which has two models - Member and ChildrenInformation.

Error:

500 Internal Server Error

If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.

I checked the log file, and this is what I found out:

TypeError (expected Hash (got Array) for param `child_info_attrib'):

Here are the other parts of my rails project

View (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 %>`

Model (Member)

 class Member < ActiveRecord::Base
    has_many :children_informations
    
    def child_info_attrib=(attribs)
        attribs.each do |attrib|
          children_informations.build(attrib)
        end
    end 
 end

Model (ChildrenInformation)

class ChildrenInformation < ActiveRecord::Base
    belongs_to :member
end

Controller (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

Development Log: http://pastebin.com/n9E2nyFv (members table has a lot of fields)

What I tried so far is to omit the nested form, and it did work.
Additionally, I based this way of using nested form through RailsCasts (http://railscasts.com/episodes/73-complex-forms-part-1).

How can I submit it successfully with the nested form?

Thank you in advance! :)

È stato utile?

Soluzione 3

It was a mistake that I defaced the note of RailsCasts episode about nested forms (http://railscasts.com/episodes/73-complex-forms-part-1) that it is outdated, and I should instead follow the latest episode of the said topic (http://railscasts.com/episodes/196-nested-model-form-part-1). It worked now :)

Altri suggerimenti

I think you're building your nested form incorrectly:

#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 %>

You'd need to do this:

View

<%= 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 %>

This will create the form elements with the correct data, but I also think your handling of the data can be improved. As you're on Rails 3, I'll wait for a comment to see if you'd like me to write some code for it!

the railscast episode you are following is dated 2007. I don't think this approach is the best in doing nested forms.

this

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

could be simplified to this (if you are using rails 3.x >)

attr_accessible :childs_attributes
accepts_nested_attributes_for :childs

If you want references or some tutorials to follow I would recommend
http://railscasts.com/episodes/196-nested-model-form-revised
http://railscasts.com/episodes/197-nested-model-form-part-2

or if you don't those, you could look at this gem
https://github.com/nathanvda/cocoon
which simplifies what you are trying to achieve.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top