Today I wanted to share something that helped me finally gain enough control over
fields_for to display components of an external object’s external object. There has to be a better way to say that but I’m drawing a blank currently. Any suggestions?
Over the past few posts (aside from the refactor posts) I’ve been exploring the ins and outs of the Rails form helper
accepts_nested_attributes_for as I need/want to have one Object’s form to save, retrieve and update values all in one place.
As I took some time yesterday to go over my project to set a game plan for the week, I was surprised to see that some of my deep nested
fields_for text fields were not rendering in my browser.
Oh, what to do?
Solution to Deeply Nested
So I’m going to briefly describe the problem set and then demonstrate the solution she wrote about.
To set the stage, lets assume that the image above is showing a page render after entering in data into the address fields and hitting the update button. In actuality what was occurring was these
Address form fields weren’t rendering at all.
Next lets look back at a code sample from a previous post to see how to nest
fields_for in a multi-part form.
The gist is this. My parent object’s iterative variable has been named
f, this means that whenever I’m creating form fields for parent object attributes, I’d use this
f variable. And when the time comes to include a form field from another object I would do something like this :
From line: 21 in the illustration above.
<%= f.fields_for :teacher_aids do |teach_aid| %># attribute ERB code goes here<% end %>
Now what happens when we want to add a
teacher_aid‘s primary phone number? Well going back to our parent object’s
f variable chat, we now find ourselves a level down, in an iterative variable named
teacher_aid. So our nested
fields_for definition would look like so:
<%= f.fields_for :teacher_aids do |teach_aid| %><%= teach_aid.text_field :first_name %>...<%= teach_aid.fields_for :primary_phone do |phone1| %><%= phone1.phone_field :area_code %><%= phone1.phone_field :number %><% end %><% end %>
And then we would use the new
phone1 variable in between the pipe symbols to create text fields for only teacher_aid’s primary phone attributes.
Without the solution I just learned over the weekend from Kathryn’s blog post, either my form fields for primary phone would not render at all, or would render but not save or retrieve values.
Her solution was to build the component object’s in the view, heres a sample from my project.
In the index view, since we are creating a new record to save we can just do something like so:
Line: 138 contains the solution. As a second parameter for
fields_for, Kathryn instructed us to use the iterative variable chained to
object which allows us to dynamically set the object to which this
Address is associated with.
She goes into more detail for what to do in the case of the edit template.
And here you have it! This image was taken after saving the form field data and pulling up the edit template. The values have been saved, and are now being retrieved in the even that a user wants to update the values in the various address fields.
Have a great week!