My idiotic encounter with accepts_nested_attributes_for in Rails 3

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!!

 

3 Comments

Did this waste your time or did you benefit from it? Let me know :-) Feel free to add your own views too