双父嵌套资源或多态是否适合我?

时间:2013-08-07 08:09:11

标签: ruby-on-rails ruby-on-rails-3.2 routes

我有一个名为evaluation的模型belongs_to另外两个模型 - studentgoal

在研究如何设置这种路由关联时,起初我认为多态关联最好,但现在我不太确定。我对多态关系的理解不是那么坚固,所以如果我错了请纠正我,但在我的情况下evaluations似乎可以belong_to studentgoal同样地,但那不是我想要的。

事实上,给定evaluation belong_to同时具有student a goal非常重要。 Rails routing guide特别提到拥有三重嵌套资源并不是一个好主意:

rails routing guide

但是,即使这个警告也没有用,例如photos belong_to magazines belong to publishers - 而在我的情况下evaluations 1}}同时应belong_to studentsgoals

我试过

resources :students, :goals do 
  resources :evaluations
end

但这仅为students/evaluationsgoals/evaluations创建了资源 - 所以我的问题是:

如何路由到属于两个父模型的同等加权的嵌套资源(我只需要创建,更新和销毁操作,因为evaluations只能在上下文中查看一个/两个父模型)?

OR

我是否应该使用多态关联进行此操作,而我只是不能正确理解它?

2 个答案:

答案 0 :(得分:1)

我会使用多态:

<强>的routes.rb

resources :students do
  resources :evaluations
end

resources :goals do
  resources :evaluations
end

<强>模型/ evaluation.rb

class Evaluation < ActiveRecord::Base
  attr_accessible :some_attribute
  belongs_to :evaluable, polymorphic: true
end

<强>模型/ student.rb

class Student < ActiveRecord::Base
  attr_accessible :some_attribute
  has_many :evaluations, as: :evaluable
end

<强>模型/ goal.rb

class Goal < ActiveRecord::Base
  attr_accessible :some_attribute
  has_many :evaluations, as: :evaluable
end

你的目标与学生之间的关系如下:

id    evaluable_id  evaluable_type    other_field
 1               4       'Goal'         'other goal content 1'
 2               1       'Student'      'other student content 1'
 3               1       'Student'      'other student content 2'

现在你可以打电话:

Student.find(1).evaluations

将返回带有ID 2和3的评估,因为它们具有evaluateable_type = Student,其中可评估的id = 1.或者:

Goal.find(4).evaluations

将返回id为1的评估,猜测原因。 :) 是的,使用多态关联。

答案 1 :(得分:0)

尽管rmagnum2002对使用多态关联的解决方案给出了非常好的答案,但我无法让它对我有用。最后,我将evaluations归属于goalsstudents。至于路由,我的routes.rb的相关部分如下所示:

resources :students, :goals, :only => :stub do
  resources :evaluations, :only => [:new, :create, :edit, :update, :destroy]
end  

并生成:

student_evaluations POST   /students/:student_id/evaluations(.:format)                   evaluations#create
new_student_evaluation GET    /students/:student_id/evaluations/new(.:format)               evaluations#new
edit_student_evaluation GET    /students/:student_id/evaluations/:id/edit(.:format)          evaluations#edit
student_evaluation PUT    /students/:student_id/evaluations/:id(.:format)               evaluations#update
                       DELETE /students/:student_id/evaluations/:id(.:format)               evaluations#destroy
goal_evaluations POST   /goals/:goal_id/evaluations(.:format)                         evaluations#create
new_goal_evaluation GET    /goals/:goal_id/evaluations/new(.:format)                     evaluations#new
edit_goal_evaluation GET    /goals/:goal_id/evaluations/:id/edit(.:format)                evaluations#edit
goal_evaluation PUT    /goals/:goal_id/evaluations/:id(.:format)                     evaluations#update
                       DELETE /goals/:goal_id/evaluations/:id(.:format)                     evaluations#destroy

最重要的是在数据库中生成一个如下所示的评估模型:

db view

因此对于每个evaluation,同时存在相应的goal_id student_id