zkcro
zkcro

Reputation: 4344

Error using nested_form gem with empty association

In my rails app, I have two models, a ClientPage and a ContentSection, where ClientPage has_many :content_sections. I'm using the nested_form gem to both models to be edited with the same form. This works fine as long as the ClientPage has at least one ContentSection, but if there are no associated ClientSections, the using nested_form's link_to_add method throws the following NoMethodError:

undefined method `values_at' for nil:NilClass

The form is structured as follows:

<%= nested_form_for page, form_options do |f| %>
  # ClientPage fields

  # ClientSections

  <%= f.link_to_add "Add new section", :content_sections %>
<% end %>

As long as there is at least one ClientSection associated with the page, this works fine. As soon as there isn't, the error is thrown. Removing the link_to_add also stops the error from being thrown. (There's actually a second nested model under ContentSection, and the same issue arises if there are no associated models.)

Not sure what I'm fairly obvious thing I'm missing, but any pointers or suggestions would be greatly appreciated.

Upvotes: 3

Views: 947

Answers (1)

zkcro
zkcro

Reputation: 4344

Finally worked this out -- the error was due to the fact that I was using the gem in a slightly non-standard way. Within the form, instead of rendering all of the content sections the standard way:

<%= f.fields_for :content_sections do |section_form| %>
  # section fields
<% end %>

I put it inside a loop, as I needed the index of each item (which is not stored within the model itself):

<% page.content_sections.each_with_index do |section, index| %>
  <%= f.fields_for :content_sections, section do |section_form| %>
    # section fields
  <% end %>
<% end %>

The issue doing it this way is that the fields_for method does not get called if the association is empty, and as such the gem cannot build the blueprint for the object (which is used to add in the extra item when link_to_add is called).

The solution was to make sure fields_for got called even if the association was empty:

<% if page.content_sections.empty? %>
  <%= f.fields_for :content_sections do |section_form| %>
    # section fields
  <% end %>
<% end %>

Upvotes: 5

Related Questions