ruby-on-railsruby-on-rails-4devisenested-formsnested-form-for

Using devise with nested form on sign_up


The form doesn't show the Pessoa's field, what's wrong?

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <h4>Usuário</h4>

    <%= f.email_field :email, autofocus: true %>

    <% if @minimum_password_length %>
      <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "off" %>

    <%= f.password_field :password_confirmation, autocomplete: "off" %>

  <h4>Pessoa</h4>

  <%= f.fields_for :pessoa do |p| %>
      <%= p.text_field :nome %>   
  <% end %>

  <div class="actions">
    <%= f.submit "Cadastrar" %>
  </div>

<% end %>

I just see, email, password and password confirmation... class User:

class Usuario < ActiveRecord::Base

  has_one :pessoa
  has_many :pedidos, through: :pessoa

  accepts_nested_attributes_for :pessoa

And RegistrationController:

class Usuarios::RegistrationsController < Devise::RegistrationsController

  def new
    build_resource(sign_up_params)
    self.resource.pessoa = Pessoa.new
    respond_with self.resource
  end

  def create
    super
  end

  private

  def sign_up_params
    params.require(:user).permit(pessoas_attributes: [:nome])
  end

end

Pessoa belongs to Usuario, ok? And need show email, password, password confirmation and name. When submit need save in two tables (Usuarios and Pessoas) the values registered. What I'm wrong? Thanks!

EDIT

The form Pessoa show, but after I filled out the data, dont save in DB, why? I did what I was asked to do. The user values save ok, but pessoas dont.


Solution

  • In your controller in the sign_up_params change from pessoas_attributes to pessoa_attributes since you have a has_one relationship in your models.

    also in the sign_up_params method yo need to change your params key, you have :user but instead it seems to be :usuario

    Also: You can add the following method to the User model:

    user.rb

    def with_pessoa
      self.pessoa = Pessoa.new
      self
    end
    

    And modify the view:

    new.html.erb

    ...
    <% form_for [resource_name, resource.with_pessoa], :url => registration_path(resource_name) do |f| %>
    ...
      <% f.fields_for :pessoa do |pessoa_form| %>
      ...
      <% end %>
    

    This way, you'll have the nested form to add one pessoa to the user. To dynamically add multiple pessoas to the user, check the Railcast #197 by Ryan Bates. Make sure you are passing the pair of resources as an array, otherwide you will get an error like this: "wrong number of arguments (3 for 2)".