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 %>
<%= f.fields_for :admin do |f2| %>
try removing the f.
try with just this:
<%= fields_for :admin do |f2| %>
There is two way to use field_for:
A generic one. (like my example).
A nested one.
To use the nested field_for (f.field_for), your model object must be setup correctly
Ex: Relation with @school and @admin
class School< ActiveRecord::Base
has_one :admin
accepts_nested_attributes_for :admin
end
In the end, there is multiple ways of using field_for depending on how you setup the relations on your model object.
This guide explain in details all the possible setup. You might find why it was not working for you.
My bet is your Admin and School model object are not in a relation, or you didn't put the accepts_nested_attributes_for :admin in your School object.
TLDR:
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:
fields_for
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"
}
}
f.fields_for
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