【问题标题】:Dual-parent nested resources or is polymorphism right for me?双父嵌套资源或多态性适合我吗?
【发布时间】:2013-08-08 12:17:03
【问题描述】:

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

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

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

但是,即使这个警告也没有帮助,因为在这个例子中 photos belong_to magazines 反过来 belong to publishers - 而在我的情况下 evaluations 应该 belong_to studentsgoals 同时。

我试过了

resources :students, :goals do 
  resources :evaluations
end

但这只会为students/evaluationsgoals/evaluations 创建一个资源 - 所以我的问题是:

如何路由到一个嵌套资源,该资源具有同等权重属于两个父模型(我只需要创建、更新和销毁操作,因为evaluations 只会在一个/两个父模型)?

我是否应该使用多态关联来执行此操作,而我只是没有正确理解它?

【问题讨论】:

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


    【解决方案1】:

    我会使用多态:

    routes.rb

    resources :students do
      resources :evaluations
    end
    
    resources :goals do
      resources :evaluations
    end
    

    models/evaluation.rb

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

    models/student.rb

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

    models/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 的评估,因为它们有 evaluable_type = Student,其中可评估的 id = 1。或者:

    Goal.find(4).evaluations
    

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

    【讨论】:

    • 我试试看。路由文件应该是什么样的?
    • @dax 这个答案是否解决了您的问题?如果不只是让我知道,所以我将其删除.. 无需在 SO 上保留垃圾。
    • @magnum2002,我有一点计划外的休息时间,但我会在今天的某个时候回到正题。今天我会接受或添加另一个答案。感谢您的跟踪!
    【解决方案2】:

    虽然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
    

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

    所以对于每个evaluation,同时有一个对应的goal_id student_id

    【讨论】:

      猜你喜欢
      • 2013-07-24
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多