Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails has_many :through nested form

I have just jumped into has_many :through association. I'm trying to implement the ability to save data for all 3 tables (Physician, Patient and association table) through a single form.

My migrations:

class CreatePhysicians < ActiveRecord::Migration   def self.up     create_table :physicians do |t|       t.string :name       t.timestamps     end   end end  class CreatePatients < ActiveRecord::Migration   def self.up     create_table :patients do |t|       t.string :name       t.timestamps     end   end end  class CreateAppointments < ActiveRecord::Migration   def self.up     create_table :appointments do |t|       t.integer :physician_id       t.integer :patient_id       t.date :appointment_date       t.timestamps     end   end end 

My models:

class Patient < ActiveRecord::Base   has_many :appointments   has_many :physicians, :through => :appointments   accepts_nested_attributes_for :appointments   accepts_nested_attributes_for :physicians end class Physician < ActiveRecord::Base   has_many :appointments   has_many :patients, :through => :appointments   accepts_nested_attributes_for :patients   accepts_nested_attributes_for :appointments end class Appointment < ActiveRecord::Base   belongs_to :physician   belongs_to :patient end 

My controller:

def new     @patient = Patient.new     @patient.physicians.build     @patient.appointments.build end 

My view (new.html.rb):

<% form_for(@patient) do |patient_form| %>   <%= patient_form.error_messages %>   <p>     <%= patient_form.label :name, "Patient Name" %>     <%= patient_form.text_field :name %>   </p>   <%  patient_form.fields_for :physicians do |physician_form| %>     <p>       <%= physician_form.label :name, "Physician Name" %>       <%= physician_form.text_field :name %>     </p>  <% end %>    <p>     <%= patient_form.submit 'Create' %>   </p> <% end %>  <%= link_to 'Back', patients_path %> 

I'm able to create a new Patient, Physician and associated record for an Appointment, but now I want to have field for appointment_date too in form. Where should I place fields for Appointments and what changes are required in my controller? I tried googling and tried this, but got stuck in some or other error implementing it.

like image 923
S R Avatar asked Nov 22 '12 06:11

S R


2 Answers

Ok, this little bugger of a question stumped me for a few hours, so I'm going to post my working solution on here in hopes it shaves some time for peeps. This is for Rails 4.0 and Ruby 2.0. This also overcame a "symbol to integer conversion" issue I had.

Models:

class Patient < ActiveRecord::Base    has_many :appointments   has_many :physicians, :through: :appointments   accepts_nested_attributes_for :appointments end   class Appointment < ActiveRecord::Base   belongs_to :physician    belongs_to :patient   accepts_nested_attributes_for :physician end  class Physicians < ActiveRecord::Base   has_many :appointments   has_many :patients, through: :appointments end 

Controller:

def new   @patient= Patient.new    @appointments = @patient.appointments.build   @physician = @appointments.build_physician  end  def create   Patient.new(patient_params) end   def patient_params    params.require(:patient).permit(:id, appointments_attributes: [:id, :appointment_time, physician_attributes: [:id ] ) end 

View

<% form_for(@patient) do |patient_form| %>   <%= patient_form.error_messages %>   <p>     <%= patient_form.label :name, "Patient Name" %>     <%= patient_form.text_field :name %>   </p>    <% patient_form.fields_for :appointments do |appointment_form| %>     <p>       <%= appointment_form.label :appointment_date, "Appointment Date" %>       <%= appointment_form.date_field :appointment_date %>     </p>      <% appointment_form.fields_for :physician do |physician_form| %>       <p>         <%= physician_form.label :name, "Physician Name" %>         <%= physician_form.text_field :name %>       </p>     <% end %>   <% end %>    <p>     <%= patient_form.submit 'Create' %>   </p> <% end %>  <%= link_to 'Back', patients_path %> 
like image 102
guy8214 Avatar answered Oct 06 '22 12:10

guy8214


"i got it working. I just changed models as follows" : quoted from Shruti in the comments above

class Patient < ActiveRecord::Base    has_many :appointments, :dependent => :destroy    has_many :physicians, :through => :appointments   accepts_nested_attributes_for :appointments end   class Appointment < ActiveRecord::Base   belongs_to :physician    belongs_to :patient   accepts_nested_attributes_for :physician end 
like image 20
ctilley79 Avatar answered Oct 06 '22 13:10

ctilley79