I have an edit form that is not a devise form (i have a devise edit on a different view) to edit a users details. However the form inputs only appear if the data is already there. So a user is unable to add new details to the form, as the inputs don't appear at all.
Is this happening as i'm not using a devise form view?
This is the code in my own edit file:
<%= render "devise/registrations/details", f: f, resource: @resource, addressable: @resource, default_location: nil %>
Then in the devise/registration/details i have this:
<%= f.simple_fields_for :address do |fields| %>
<%= render "address/fields", fields: fields, addressable: addressable, resource: resource %>
<% end %>
However, i think the inputs are not showing up as fields
are blank in the iteration. However these fields are showing up in the actual devise/edit file, even if they are blank, just not in my new one.
When using fields_for
and simple_fields_for
(which is basically just a pimped up version of the former) you have to "seed" the inputs in order for them to appear.
Consider this simplified plain rails example:
class UsersController < ApplicationController
def new
@user = User.new
@user.build_address
end
# ...
end
<%= simple_form_for(@user) do |f| %>
<%= f.simple_fields_for(:address) do |af| %>
<%= af.input :street %>
<% end %>
<% end %>
If we remove the line @user.build_address
there will be no nested inputs. Thats because simple_fields_for
calls the method #address
on @user
and creates inputs for the record. If the association is one or many to many it would iterate through the association. If the method returns nil or empty there are no inputs to create - it would be like calling form_for
with nil.
You can also pass a second argument to fields_for
to manually specify the record object:
<%= simple_form_for(@user) do |f| %>
<%= f.simple_fields_for(:address, @user.address || @user.build_address) do |af| %>
<%= af.input :street %>
<% end %>
<% end %>
In Devise you can do this by passing a block to super or by overriding #build_resource
.
class MyRegistationsController < Devise::RegistrationsController
def new
super { |resource| resource.build_address }
end
end