I was using accepts_nested_attributes_for for the first times in Rails 3 to create forms that have fields from a parent model and its child model. I made a number of mistakes that make me feel like an idiot right now. Actually, the last one did but I saw it fit to blog about it in case anyone else finds themselves wasting an hour or more trying to get their forms to work.
N/B
- I was using Rails 3.0.5 and Ruby 1.8.7 (MRI)
- The Parent model had a has_one relationship to the child. (This shouldn’t matter though)
Mistake 1
In this case, my fields_for helper wasn’t evaluating to anything. The textfields and textareas were therefore not being created in the view. The issue was that in Rails 3, the helpers form_for and fields_for use <%= instead of <% !! I used the latter. (i)
Therefore, my form_for and fields_for helpers should have looked like this:
<%= form_for ......... %> <%= fields_for ......... %>
This made the text fields visible but the values weren’t there.
Mistake 2
I didn’t make the attributes of the child model accessible to the parent model. This is done using attr_accessible and passing child_attributes.
e.g
def Dog < ActiveRecord::Base has_one :puppy accepts_nested_attributes_for :puppy attr_accessible: puppy_attributes end
Mistake 3 (Epic Fail)
Now this is the part that got me cursing all over the place. My form was being created using the variable from the controller rather than a symbol i.e
<%= form_for @dog do |f| %>
INSTEAD OF
<%= form_for :dog do |f| %>
The field_for was supposed to accept an object of the puppy model referenced from the @dog variable passed to the form. Problem is I was so frustrated by the fact that my text fields were empty that I started binging on Google search results and ended up with a fields_for that accepted the object of the puppy model as a symbol hahaha! yeah stupid.. i know. This is how it looked:
<%= fields_for :puppy do |puppy_fields| %> <%= puppy_fields.text_field :breed %> <% end %>
It obviously should have been like this:
<%= fields_for @dog.puppy do |puppy_fields| %> <%= puppy_fields.text_field :breed %> <% end %>
I’m going to cringe away in a dark corner now… Cheers!!