When I run the rails server and go to the school/new page on my site, the field with the label "school" where I can enter the school's name appears, but all the other fields under fields_for which are for entering the school administrator's info do not show up on my site -- when I use "inspect element" on my form it is like they are not even there. Why aren't they appearing on my page?
<%= form_for(@school) do |f| %>
<% if @school.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@school.errors.count, "error") %> prohibited this school from being saved:</h2>
<ul>
<% @school.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :school %><br />
<%= f.text_field :name %>
</div>
<%= f.fields_for :admin do |f2| %>
<div class="field">
<%= f2.label "administrator name" %><br />
<%= f2.text_field :name %>
</div>
<div class="field">
<%= f2.label "administrator email" %><br />
<%= f2.text_field :email %>
</div>
<div class="field">
<%= f2.label "administrator gender" %><br />
<%= f2.text_field :gender %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
For my purposes, I had to make sure the form object's child association was populated with a new record. Originally, the parent object's child association returned nil. I just had to instantiate an object and the form rendered correctly.
In case anyone arrives here from Google, I had a the same problem as the poster, but the accepted answer didn't help me.
First, some background. When you use the plain fields_for
instead of f.fields_for
, the fields are rendered differently. The plain version (as suggested above) does not associate the fields rendered with the form's object. Look at the different outputs:
form_for @parent_instance do |f|
f.text_field :parent_field
fields_for :child_obj do |child_fields|
child_fields.text_field :child_field
end
end
Renders
<input id="parent_class_parent_field" name="parent_class[parent_field]" type="text" />
<input id="child_class_child_field" name="child_class[child_field]" type="text" />
Which Rails will parse into these parameters:
{ "parent_class" => {
"parent_field" => "Parent field value"
},
"child_class" => {
"child_field" => "Child field value"
}
}
form_for @parent_instance do |f|
f.text_field :parent_field
f.fields_for :child_obj do |child_fields|
child_fields.text_field :child_field
end
end
Renders
<input id="parent_class_parent_field" name="parent_class[parent_field]" type="text" />
<input id="parent_class_child_class_child_field" name="parent_class[child_class][child_field]" type="text" />
Which Rails will parse into these parameters:
{ "parent_class" => {
"parent_field" => "Parent field value",
"child_class" => {
"child_field" => "Child field value"
}
}
}
The difference is that the child object's parameters only get nested under the parent when you use f.fields_for
. So using the accepted answer's suggestion of using the bare fields_for
didn't work for creating an associated record.
Turned out, the reason f.fields_for
wasn't rendering anything was because the child association was nil. To fix it and have my form render correctly and return the parameters in the properly nested way, I had to instantiate that association like this in my controller:
def new
@parent = ParentClass.new
@parent.child_obj = ChildClass.new
end