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=
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)