Skip to content

Instantly share code, notes, and snippets.

@NIA
Last active December 11, 2015 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NIA/4604572 to your computer and use it in GitHub Desktop.
Save NIA/4604572 to your computer and use it in GitHub Desktop.
# First I modify your models a bit:
Class Appointment ...
# belongs_to :doctor (replace it with this ↓)
has_one :doctor, through: :schedule # This means 'doctor_id' is not stored in appointments table, it is got from schedule via join
belongs_to :schedule
end
Class Schedule ...
belongs_to :doctor
# has_many :appointments (add this ↓)
has_many :appointments, dependent: :destroy
end
Class Doctor ...
# has_many :appointments, dependent: :destroy (replace with this ↓, dependent: moved to Schedule)
has_many :appointments, through: :schedule
has_many :schedules, dependent: :destroy
end
# -----
# Now assume that we are in the view schedules/show and
# we have @schedule set to the current schedule (in the controller):
@schedule # => returns current schedule we a showing
# You know that this:
@schedule.appointments
# ...will return the list of appointments in GIVEN schedule.
# But it is not a simple array, it is an _association_ and it has methods:
a = @schedule.appointments.build
#...returns a new appointment ASSOCIATED with current @schedule, that is, it has its schedule_id set.
# I.e, it is the same as
a = Appointment.new :schedule => @schedule
# You can check that:
a.schedule # will return @schedule
a.doctor # will return @schedule.doctor: that is how :through association works
# You see, this new appointment has no info in it, but it has two correct associations!
# So if you have your route for appointments#new is like
# new_doctor_appointment GET /:locale/doctors/:doctor_id/schedules/:schedule_id/appointments/new
# You can create a link to a appointments#new page with
a = @schedule.appointments.build
link_to "New appointment", new_doctor_appointment_path(a, locale: 'en')
# ... and it will get doctor_id and schedule_id from `a` object.
# Note that in order to make the routes look like this, you have to replace
resources :doctors do
resources :appointments
resources :schedules
end
# with
resources :doctors do
resources :schedules do
resources :appointments
end
end
# If I am right and appointments are nested in schedules, than it's better to show this in routes too.
@jmercedes
Copy link

NIA, thank you for the comments, I'm grasping the concepts. But I'm a bit lost in the controllers.

How do I pass the parameters to the doctor_controller index action?

a) @DoctorS = Doctor.all
b) @schedule = Schedule.find(params[:doctor_id] @DoctorS = @schedule.doctors.all
c) ....

In the new action I'm going to replace @doctor = Doctor.new with @doctor = schedule.build?

@jmercedes
Copy link

@NIA
Copy link
Author

NIA commented Jan 23, 2013

Wait, wait. Schedules belong to Doctor, not vice versa. You somehow reverse this, it is wrong.

That's why no modification needed in doctors_controller. It is the root of current ierarchy and it remains unchanged. @doctor = Doctor.all is ok for index action, @doctor = Doctor.new is ok for new action — no changes.

I looked your repo and see that schedules_controller is also ok. Indeed, it should not change when we move appointments inside of schedules.

You only have to modify your Appoitments controller. I will post my comments about it to the commit in your repository

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment