0

I have this model User, Entidade and Candidato.

class User < ActiveRecord::Base
  has_one :entidade
  has_one :candidato

  accepts_nested_attributes_for :entidade
  accepts_nested_attributes_for :candidato

class Candidato < ActiveRecord::Base
  belongs_to :user

class Entidade < ActiveRecord::Base
  belongs_to :user

Basically in order to register you need to specify if you want to be an Entidade or a Candidato. They have some shared attributes that i put in the User table. And the non shared attributes stay in the respective table.

This is the form:

<%= simple_form_for @user, :html => { :multipart => true } do |f| %>
          <%= render 'shared/error_messages' %>
          <%= f.input :email %>
          <%= f.input :role, :as => :hidden, :input_html => { :value => "candidato" } %>
          <%= f.input :password %>
          <%= f.input :password_confirmation, label: "Confirme a password" %>
          <%= f.input :nome %>
          <%= f.input :foto, :label => "Foto" %>
          <%= f.input :cod_postal, :label => "Código-Postal" %>
          <%= f.input :localidade %>
          <%= f.input :contacto1, :label => "Contactos" %>
          <%= f.input :contacto2, label: false %>
          <%= f.input :pagina, :label => "Página Pessoal" %>
          <%= f.fields_for :candidato do |ff| %>
            <%= ff.input :data_nascimento, :label => "Data de Nascimento" %>
            <%= ff.input :bi, :label => "Bilhete de Identidade" %>
            <%= ff.input :cv, :label => "Curriculum Vitae" %>
            <%= ff.label :area_profissional, :label => "Área Profissional" %>
            <%= ff.select :area_profissional, ["Programador_Web", "Programador_Java","Gestor"], :label => "Área Profissional"  %>
            <%= ff.input :apresentacao, :label => "Apresentação" %>
            <%= ff.select :nivel_hab, ["Secundário","Licenciatura","Mestrado","Doutoramento"], :label => "Nível de Habilitações" %>
            <%= ff.input :hab_literaria, :label => "Habilitações Literárias" %>
            <%= ff.select :situacao_prof, ["Empregado","Desempregado"], :label => "Situação Profissional" %>
            <%= ff.input :exp_profissional, :label => "Experiência Profissional" %>
          <% end %>
          <%= f.submit "Registar", class: "btn btn-large btn-primary" %>
        <% end %>

And I can't create the damn User. It keeps rendering the new page. What the hell is wrong.

This is my Controller:

class UsersController < ApplicationController
  def new
    @user = User.new
    if params[:param] == "candidato"
      @role = "candidato"
      #@user.candidato = Candidato.new
      @user.build_candidato
    else
      @role = "entidade"
      #@user.entidade = Entidade.new
      @user.build_entidade
    end
  end

  def create
    @user = User.new(user_params)
    if user_params[:role] == "candidato"
      @user.build_candidato(user_params[:candidato_attributes])
      #@user.candidato = Candidato.new(user_params[:candidato_attributes])
      if @user.save
        #Sucesso
        redirect_to root_path
      else
        #Falhou
        @role = "candidato"
        render 'new'
      end
    else
      #@user.entidade = Entidade.new(user_params[:entidade_attributes])
      @user.build_entidade(user_params[:entidade_attributes])
      if @user.save
        #Sucesso
        redirect_to root_path
      else
        #Falhou
        @role = "entidade"
        render 'new'
      end
    end
  end

  private
    def user_params
      params.require(:user).permit(:role,:email,:nome,:password,:password_confirmation,:pagina,:contacto1,:contacto2,:foto,:cod_postal,:localidade, :candidato_attributes => [:data_nascimento,:bi,:cv,:area_profissional,:apresentacao,:nivel_hab,:hab_literaria,:situacao_prof,:exp_profissional], :entidade_attributes => [:nip,:apresentacao,:atividade])
    end
end

If someone knows what's wrong please tell me

2 Answers 2

1

Problem is here in your create method you are building dependent object twice and you have has_one relationship. You object for dependent model already created on new action on parent.

Your controller should look like :

def create
  @user = User.new(user_params)
  if @user.save
    redirect_to root_path
  else
    @role = user_params[:role]
    render 'new'
  end
end

Form should look like :

<%= simple_form_for @user, :html => { :multipart => true } do |f| %>
  <%= render 'shared/error_messages' %>
  <%= f.input :email %>
  <%= f.input :role, :as => :hidden, :input_html => { :value => @role } %>
  <%= f.input :password %>
  <%= f.input :password_confirmation, label: "Confirme a password" %>
  <%= f.input :nome %>
  <%= f.input :foto, :label => "Foto" %>
  <%= f.input :cod_postal, :label => "Código-Postal" %>
  <%= f.input :localidade %>
  <%= f.input :contacto1, :label => "Contactos" %>
  <%= f.input :contacto2, label: false %>
  <%= f.input :pagina, :label => "Página Pessoal" %>
  <% if @role == "candidato" %>
    <%= f.fields_for :candidato do |ff| %>
      <%= ff.input :data_nascimento, :label => "Data de Nascimento" %>
      <%= ff.input :bi, :label => "Bilhete de Identidade" %>
      <%= ff.input :cv, :label => "Curriculum Vitae" %>
      <%= ff.label :area_profissional, :label => "Área Profissional" %>
      <%= ff.select :area_profissional, ["Programador_Web", "Programador_Java","Gestor"], :label => "Área Profissional"  %>
      <%= ff.input :apresentacao, :label => "Apresentação" %>
      <%= ff.select :nivel_hab, ["Secundário","Licenciatura","Mestrado","Doutoramento"], :label => "Nível de Habilitações" %>
      <%= ff.input :hab_literaria, :label => "Habilitações Literárias" %>
      <%= ff.select :situacao_prof, ["Empregado","Desempregado"], :label => "Situação Profissional" %>
      <%= ff.input :exp_profissional, :label => "Experiência Profissional" %>
    <% end %>
  <%else%>
    <%= f.fields_for :entidade do |ff| %>
      <%= ff.input :atividade, :label => "atividade" %>
      <%= ff.input :apresentacao, :label => "apresentacao" %>
      <%= ff.input :nip, :label => "nip" %>
    <% end %>
  <% end %>
  <%= f.submit "Registar", class: "btn btn-large btn-primary" %>
<% end %>

You also have to add :id and _destroy in attributes. It will used at the time of edit and delete child model.

def user_params
  params.require(:user).permit(:role,:email,:nome,:password,:password_confirmation,:pagina,:contacto1,:contacto2,:foto,:cod_postal,:localidade, :candidato_attributes => [:id, :data_nascimento,:bi,:cv,:area_profissional,:apresentacao,:nivel_hab,:hab_literaria,:situacao_prof,:exp_profissional, :_destroy], :entidade_attributes => [:id, :nip,:apresentacao,:atividade, :_destroy])
end
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I've been hitting on this for hours. I feel stupid. I forgot the id's and your code is much cleaner. Thanks again!
1
#app/controllers/users_controller.rb
Class UsersController < ApplicationController
   def new
      @user = User.new
      @user.send("build_#{params[:param]}")
   end

   def create
      @user = User.new user_params
      @user.save
   end

   private

   def user_params
      params.require(:user).permit(:role,:email,:nome,:password,:password_confirmation,:pagina,:contacto1,:contacto2,:foto,:cod_postal,:localidade, :candidato_attributes => [:data_nascimento,:bi,:cv,:area_profissional,:apresentacao,:nivel_hab,:hab_literaria,:situacao_prof,:exp_profissional], :entidade_attributes => [:nip,:apresentacao,:atividade])
   end
end

When you pass nested attributes, you only need to build the initial associative object

In your create method, you're building the associative data again. A much better way will be to use the code above (albeit edited to represent your redirects), to create the User object

Validations aside, I don't see any reason why the above code wouldn't work with your form

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.