Project Ramon

A learning journey from a Ruby noob perspective

Exploring Rails: Nested fields_for

Hello!

Today I wanted to share something that helped me finally gain enough control over accepts_nested_attributes_for‘s 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 fields_for

I owe my success of this hurdle entirely to Kathryn Blackley and her very insightful blog post on this exact topic.

So I’m going to briefly describe the problem set and then demonstrate the solution she wrote about.

nested_fields_for1_img1

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.

nested_fields_for1_img2

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

 

I covered this is greater detail in this post and this one.

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:

nested_fields_for1_img3

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.

The Results

nested_fields_for1_img4

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!

Stay tuned…

Advertisements

Categories: Newbie, Ruby on rails

Tags: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s