0

I have used a combination of answers from 21222015, 17572279, 2663141, and RailsGuide to try and get multiple interdependent models to be created from a form.

In my application Users are used for authentication and Clinicians and Patients are models for the two different types of Users. Clinicians and Patients have almost no attributes in common so creating separate models made sense.

I would like to be able to create a patient or clinician and a user at the same time on a form. Patients and clinicians are both connected to their user by a user_id integer field.

Right now patients and clinicians belongs_to a user (patients also belongs_to a clinician and a clinician has_many patients):

class Patient < ActiveRecord::Base
 belongs_to :clinician
 belongs_to :user

 def set_user_id_from_user
   patient.user_id = user.id
 end

 before_validation :set_user_id_from_user
end 

A user has_one patient or clinician:

class User < ActiveRecord::Base
 has_secure_password
  has_one :patient, :dependent => :destroy
  has_one :clinician, :dependent => :destroy
  accepts_nested_attributes_for :patient,  :allow_destroy => true 
  accepts_nested_attributes_for :clinician,  :allow_destroy => true 

  validates :email, presence: true
  validates_uniqueness_of :email
end

I am trying to create a user and a patient on the new.html.erb - patients page using accepts_nested_attributes_for. I followed the RailsCast Nested Model Form Part 1 as it was recommended as an answer to SO question 10058584. This is my form:

   <%= form_for @user do |form| %>
      <p>
        <div class="form-group">
          <%= form.label :email %>
          <%= form.text_field :email, class: "form-control", placeholder: "email address"  %>
        </div>
        <div class="form-group">
          <%= form.label :password %>
          <%= form.password_field :password, class: "form-control", placeholder: "enter password"  %>
        </div>
      </p>
      <%= form.fields_for :patient do |builder| %>
        <p>
          <div class="form-group">
            <%= builder.label :first_name %>
            <%= builder.text_field :first_name, class: "form-control", placeholder: "First name" %>
          </div>

          <div class="form-group">
            <%= builder.label :last_name %>
            <%= builder.text_field :last_name, class: "form-control", placeholder: "Last name" %>
          </div>

          <div class="form-group">
            <%= builder.label :diagnosis %>
            <%= builder.text_field :diagnosis, class: "form-control", placeholder: "Diagnosis" %>
          </div>

          <div class="form-group">
            <%= builder.label :gender_id %>
            <%= builder.collection_select :gender_id, Gender.all, :id, :gender_type, :prompt => true, class: "form-control" %>
          </div>

          <div class="form-group">
            <%= builder.label :age %>
            <%= builder.text_field :age, class: "form-control", placeholder: "Age" %>
          </div>
        </p>
      <% end %>
      <%= form.button 'Create Patient', class: "btn btn-u btn-success" %>
    <% end %>

In my UsersController I have:

def new
  @user = User.new
end

def create
  @user = User.create(user_params)
  if @user.save
    redirect_to user_path(@user), notice: "User created!"
  else
    render "new"
  end
end
  private

def user_params
  params.require(:user).permit(:email, :password, patient_attributes: [ :first_name,:last_name,:user_id,:diagnosis,:gender_id,:age,:address, :email, :password, :phone_number, :caregiver_name, :other_symptom, :goals_of_care, :patient_deceased, :patient_archived ])
end

All of this currently gives me a form that only shows the two user fields: email and password. When submitted I get a new user created but no patient is created.

How do I get the patient fields to appear on the form and have a patient created that has a user_id that connects it to the user created at the same time?

Eventually I need to have it possible to create either a patient or a clinician when a user is created; maybe by making it so that that a patient/clinician accepts_nested_attributes_for a user and have the form for each?

Any advice would be really appreciated, thanks

Community
  • 1
  • 1
Skiapex
  • 133
  • 1
  • 14

1 Answers1

1

I think that in order for your patient form fields to show up, you need to say @user.build_patient in your new action in your UsersController. This initializes a patient that is associated with the User instance you created.

In case it helps anyone else, if the relationship between patient and user was a has_many instead of a has_one, then the syntax would be @user.patient.build thenew action.

Hannah
  • 136
  • 5
  • Ah, sorry--the syntax is slightly different for a `has_one` relationship vs. a `has_many`, I'll update my answer. – Hannah Apr 30 '15 at 05:43
  • Do you know how I would make it so that either a patient or a clinician can be made from a new user? right now it is just for a patient. Thanks – Skiapex Apr 30 '15 at 17:35
  • Good, I'm glad that worked! Regarding this last question, since it sounds like a user is either a patient or a clinician (not both), if you want to use regular ol' rails like you are currently doing, I think the most straightforward thing to do is have a new_patient action and a new_clinician action, each with their own forms. This way you can initialize the correct user relationship to operate on in the form. Or are you saying that the form will be the exact same whether the user is a clinician or a patient? – Hannah Apr 30 '15 at 18:16
  • I think I will switch it so that a `user` `belongs_to` a `clinician` or `patient` and they each `has_one` `user`; and they flip everything so that I'm using the patient and clinician controllers and having them `build_user`. What do you think of this idea? I tried using http://jsfiddle.net/w3pGr/ to get it so that I can switch between on the user form and can get the patient part to disappear when I select clinician as the user type but can't get the clinician form to show up - my js skills are non existent... – Skiapex Apr 30 '15 at 21:59
  • You could do just what you say where you flip around the relationships (so now your `user` would have a `user_type` which is either 'clinician' or 'patient'), but then you can still use your `UsersController`, but have a checkbox or dropdown on the form that corresponds to `user_type`--that way when you create the user you'll also create the right association with either a clinician or a patient. As long as you have all the attributes inside of the `User` model now so that the form fields show up, you shouldn't have to say `build_patient` or `build_clinician` anymore. – Hannah Apr 30 '15 at 23:22