0
votes

i'm new to both rails and web-dev.

currently i'm studding "active record Associations" in rails 4

and i got confused on usage of "has_many" vs "has_many, through" relation.

for example, if i have Physician, Appointment, and Patient model in my schema.(As rails guide provides)

and rails tutorial suggests me to do like this.


class Physician < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
end

class Appointment < ApplicationRecord
  belongs_to :physician
  belongs_to :patient
end

class Patient < ApplicationRecord
  has_many :appointments
  has_many :physicians, through: :appointments
end

but what if i make relation like this


class Physician < ApplicationRecord
  has_many :appointments
end

class Appointment < ApplicationRecord
  belongs_to :physician
  has_many :patients
end

class Patient < ApplicationRecord
  belongs_to :appointment
end

i think both will work fine.

but i want to know whats the differences and why they made "has_many, through" relations.

thank you for reading my question.

1
I think it depends on what you need. With your set up relation, how do you get physicians who have appointments of a specific patient?Thanh

1 Answers

0
votes

has_many through is a way to join two unrelated, independent models/tables and to reduce duplicates/redundancy in tables, where has_many states more directive relation.

Maybe example with appointments and physicians isn't clear. I'll give a different one.

class Artist
  has_many :paintings
  has_many :purchases
  has_many :buyers, through: :purchases
end

class Painting
  belongs_to :artist
end

class Purchase
  belongs_to :painting
  belongs_to :buyer
end

class Buyer
   has_many :paintings_buyers
   has_many :painting, through: :purchases
end

Talking about your example.

First, there is no convenient way for you to get physician's patents. The only way is:

physician.appoitments.map(&:patient).uniq

Which will result in

  1. poor performance
  2. inability to filter entities with sql, only with ruby(again poor performance)

Also, did you notice I used uniq? That's because patient's table will have lots of duplicates when the same patients will be appointed multiple times to the same physician.