如何资源管理与关联模型的多态关联?

时间:2013-07-23 08:18:42

标签: ruby-on-rails ruby-on-rails-4 polymorphic-associations

我正在努力做到以下几点:活动可以让个别学生竞争,也可以让学生团队参与。所以我将其设置为多态,如下所示:

class Event < ActiveRecord::Base
  belongs_to :event_type
  has_many :competitors
  has_many :students, through: :competitors, :source => :participant, :source_type => 'Student'
end

class Competitor < ActiveRecord::Base
  belongs_to :event
  belongs_to :participant, polymorphic: true

  # also has other attributes, like points, and grade
end

class Student < ActiveRecord::Base
  has_many :competitors, :as => :participant
  has_many :events, :through => :competitors
end

class Team < ActiveRecord::Base
  has_many :competitors, :as => :participant
  has_many :events, :through => :competitors
  has_many :team_members
  has_many :students, :through => :team_members
end

tl; dr:如何使用Resourceful控制器处理这些?

我已经有一个事件控制器,它允许我CRUD它的属性。我有一个学生控制器也一样。所以现在我需要竞争对手控制器来组合它们。我在那里画了一个空白。

我想要的是能够在一个屏幕上从学生复选框列表中选择竞赛对手。如果我创建一个像

这样的嵌套路由
resources :events, shallow: true do
  resources :competitors, shallow: true
end

然后我可以转到events/1/competitors以显示竞争对手的名单。但是它应该显示团队还是学生?我不希望它成为一个混乱的if / elses。那么我应该为这两个人分别设置控制器吗?他们将如何命名?我将如何与他们互动?

假设我确实为学生竞争对手制作了一个控制器:

resources :events, shallow: true do
  resources :student_competitors, shallow: true
end

我得到events/1/student_competitors。这将显示参加该活动的所有学生的名单。假设我想使用Update按钮将该列表设为一组复选框。我将如何构建该表格?

<%= simple_form_for(@event, :html => { :class => 'form-vertical' }) do |f| %>
  <% @students.each do |student| %>
    <%= check_box_tag "event[student_ids][]", student.id, student.events.include?(@event) %>
    <span><%= student.name %></span>
  <% end %>

  <%= f.button :submit, 'Update Competitors' %>
<% end %>

这会将表单提交回events/1,而我希望将其提交给StudentCompetitors控制器,但我不能使用simple_form_for这样的集合来调用simple_form_for(@event, @competitors)并让它构建一个更新操作的路径。

基本上,我不确定如何最好地解决所有这些问题。我是否想要过于严格,坚持资源?感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我使用了一个独特的资源:

resources :events, shallow: true do
  resource :student_competitors, shallow: true
end

因此,我可以在events/1/student_competitors修改学生竞争对手,并使用simple_form_for作为:

<%= simple_form_for(:student_competitors, url: event_student_competitors_path, :method => :put, :html => { :class => 'form-vertical' }) do |f| %>