Mel Mel - 1 month ago 13
Ruby Question

Rails, Cocoon Gem - undefined method `reflect_on_association' for NilClass:Class

I am trying to setup cocoon gem for nested forms in my Rails 5 app.

Im having a problem that others have posted about, but it seems the solutions that worked for them are not working for me.

I have models for address, organisation and settings. The associations are:

Address

belongs_to :addressable, :polymorphic => true, optional: true


Organisation

has_many :addresses, as: :addressable
accepts_nested_attributes_for :addresses, reject_if: :all_blank, allow_destroy: true


Settings

has_many :addresses, as: :addressable
accepts_nested_attributes_for :addresses, reject_if: :all_blank, allow_destroy: true


My settings controller has:

def setting_params
params.require(:setting).permit( :newsletter,
addresses_attributes: [:id, :description, :unit, :building, :street_number, :street, :city, :region, :zip, :country, :time_zone, :latitude, :longitude, :_destroy]
)
end


My routes are:

resources :organisations do
namespace :contacts do
resources :addresses
resources :phones
end
end

resources :users, shallow: true do
scope module: :users do
resources :assign_roles
resources :identities
resources :org_requests
resources :profiles
resources :settings do
namespace :contacts do
resources :addresses
resources :phones
end
end
end


My address form has:

My settings form has:

<%= simple_form_for [@user, @setting] do |f| %>
<%= f.error_notification %>

<div class="form-inputs">
<%= f.input :newsletter, as: :radio_buttons, label: "Subscribe to our newsletter" %>

<%= simple_fields_for :addresses do |f| %>
<%= f.error_notification %>
<%= render 'contacts/addresses/address_fields', f: f %>
<%= link_to_add_association 'Manage address', f, :addresses, partial: 'contacts/addresses/address_fields' %>
<% end %>
</div>
<% end %>


The error says:

undefined method `reflect_on_association' for NilClass:Class


This line is highlighted in the error message:

<%= link_to_add_association 'Manage address', f, :addresses, partial: 'contacts/addresses/address_fields' %>


For others the problem has been using the singular instead of the plural; or using @addresses instead of :addresses (although some of the solutions have suggested its supposed to be @ instead of :.

I have tried each of these in each combination.

Can anyone see what I need to do to set this up?

TAKING EDMUND'S SUGGESTION

I can see from the simple form documentation that nested attributes should be handled differently in the forms.

https://github.com/plataformatec/simple_form/wiki/Nested-Models#example-for-strong-parameters

I tried changing the form to:

<%= simple_fields_for "addresses_attributes[]", address do |f| %>


That doesnt work either. I can't render a page to inspect.

The error line in this context points to a problem with the new action in my organisation controller. That has:

def new
@organisation = Organisation.new
@organisation.addresses_build
end


The error message says:

undefined method `addresses_build' for #<Organisation:0x007fcf6ff25f08>
Did you mean? addresses


I now wonder if I need to build address_attributes instead of address. But when I try I get an error that says:

undefined method `addresses_attributes_build' for #<Organisation:0x007fcf72c26d68>
Did you mean? addresses_attributes=

Answer

You have to write

f.simple_fields_for :addresses 

The f refers to the form, and you need this to be able to iterate over all child-addresses.

And secondly, it is better to have the link_to_add_association outside of the loop (otherwise you can only add a new address if there already is one?)

So write something like

<%= f.simple_fields_for :addresses do |f| %>
  <%= render 'contacts/addresses/address_fields', f: f %>
<% end %>  
<%= link_to_add_association 'Manage address', f, :addresses, partial: 'contacts/addresses/address_fields' %>    

(imho the example you refer to in the simple-form documentation is outdated and the elaborate form is not needed)