Is it possible for a model to belong_to, two models and have a nested relationship?
i.e of what i want
class trainer
has_many :appointments
end
class appointment
belong_to :trainer, :customer
end
class customer
has_many :appointments
end
at the moment i have only the customer and appointment models which are nested e.g of what i have:
create method looks like this:
def create
@appointment = @customer.appointments.build(params[:appointment])
respond_to do |format|
if @appointment.save
format.html { redirect_to([@customer, @appointment], :notice => 'Appointment was successfully created.') }
format.xml { render :xml => @appointment, :status => :created, :location => @appointment }
else
format.html { render :action => "new" }
format.xml { render :xml => @appointment.errors, :status => :unprocessable_entity }
end
end
end
in routes i have:
map.resources :patients, :has_many => [ :appointments, :visits ]
is it possible to have 2 nested relationships for 1 model? what would i have to change my create method to, if appointment also belonged to trainer as well as customer?
thanks
Assuming that you're using ActiveRecord: Having a model belong to more than one other model is possible of course (however you need to specify one belongs_to statement for each relation).
class Appointment < ActiveRecord::Base
belongs_to :trainer
belongs_to :customer
end
A belongs_to relation does not necessarily mean that the record actually has that other record related; it can also be nil. So you can have appointments that belong to a trainer but no customer and vice versa.
Actually you can even have neither a trainer nor a customer or both a trainer and a customer as well this way - if this violates your business logic, you might want to add a validation to prevent this.
Your existing controller create method should continue to work like it is, you just need to add the handling of trainer records. You can even use the same controller for handling appointment of trainers and customers by abstracting trainers and customers, e.g. into a person like this:
class AppointmentsController < ApplicationController
def create
@appointment = person.appointments.build(params[:appointment])
# ...
end
protected
def person
@person ||=
if params[:trainer_id]
Trainer.find(params[:trainer_id])
elsif params[:customer_id]
Customer.find(params[:customer_id])
end
end
end
This way, you can use the same AppointmentsController for both routes
# Use AppointmentsController for /trainers/123/appointments
# as well as for /customers/123/appointments
map.resources :trainers, :has_many => :appointments
map.resources :customers, :has_many => :appointments
Of course, this only makes sense if the logic and views behind trainer appointments and customer appointments are almost the same. If not, you can also use different controllers
# Use TrainerAppointmentsController for /trainers/123/appointments and
# CustomerAppointmentsController for /customers/123/appointments
map.resources :trainers do |trainer|
trainer.resources :appointments, :controller => 'trainer_appointments'
end
map.resources :customers do |customer|
customer.resources :appointments, :controller => 'customer_appointments'
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With