可以模拟“belongs_to”两个其他模型并具有嵌套关系?

模型是否可以属于,两个模型并具有嵌套关系?

即我想要的

class trainer has_many :appointments end class appointment belong_to :trainer, :customer end class customer has_many :appointments end 

目前我只有客户和预约模型嵌套,例如我拥有的:

create方法如下所示:

  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 

在我有的路线:

  map.resources :patients, :has_many => [ :appointments, :visits ] 

是否可以为1个模型建立2个嵌套关系? 如果约会也属于培训师和客户,我还需要改变我的创建方法?

谢谢

假设您正在使用ActiveRecord:当然可以使模型属于多个其他模型(但是您需要为每个关系指定一个belongs_to语句)。

 class Appointment < ActiveRecord::Base belongs_to :trainer belongs_to :customer end 

belongs_to关系并不一定意味着记录实际上与其他记录有关; 它也可以是零。 因此,您可以预约属于培训师而不是客户,反之亦然。

实际上,你甚至既没有培训师也没有客户,或者既没有培训师也没有顾客 - 如果这违反了你的业务逻辑,你可能想要添加一个validation来防止这种情况发生。

您现有的控制器创建方法应该继续像它一样工作,您只需要添加训练记录的处理。 您甚至可以通过抽象培训师和客户来使用相同的控制器来处理培训师和客户的预约,例如,对于这样的人:

 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 

这样,您可以对两个路由使用相同的AppointmentsController

 # 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 

当然,这只有在培训师预约和客户约会背后的逻辑和观点几乎相同时才有意义。 如果没有,您也可以使用不同的控制器

 # 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