嵌套模型,设置多个属性,一些相同和一些不同

时间:2014-07-03 14:54:15

标签: ruby-on-rails ruby

在我的Rails应用程序中,我有三个嵌套模型:一个教室,有很多学生,学生有很多作业。作业有namegrade

在添加作业时,如何列出所有学生并在每个学生旁边都有一个输入框来输入他们的单独成绩?我还需要一个输入框,为所有学生设置相同的作业名称。因此,分配name对每个人都是相同的,但每个分配都会有grade个。{/ p>

我已列出所有学生,但现在他们为每位学生提供了两个输入框namegrade。我只需要一个分配方框,每个学生旁边的每个grade一个,所有方式都相同。

我正在使用cocoon嵌套表单,BTW。这可能吗?

1 个答案:

答案 0 :(得分:0)

所有学生都完成了相同的“作业”,但是获得了单独的“成绩”,但听起来就像在你的图式中你有作为任务和成绩的双重任务,这可能是一个错误。事实上,您将使用相同的name进行多次分配,这是您的架构不理想的一个重要线索。相反,如果我们将Assignment和Grade视为两个独立的东西,嵌套变得更自然:

class Student < ActiveRecord::Base
  belongs_to :classroom
  has_many :grades
  has_many :assignments, through: :grades
end

class Grade < ActiveRecord::Base
  belongs_to :student
  belongs_to :assignment

  # attributes: `score`
end

class Assignment < ActiveRecord::Base
  has_many :students, through: :classroom
  belongs_to :classroom

  # attributes: `name`

  accept_nested_attributes_for :grades

  # a method to initialize a Grade for each Student in the associated Classroom
  # (doesn't assign a score or save the Grade yet)
  def build_grades_for_classroom_students
    students.each {|student| grades << student.grades.build }
    grades
  end
end

这将对应于这样的架构:

    Student
  .*  |    *
 .    *     \
.   Grade    Classroom
.     *     /
 .    |    *
   Assignment

(其中*表示has_many关系的“多个”结尾,例如“学生has_many成绩”,. . .has_many … through关系。 )

这将为您的用例提供很大的灵活性,并允许您在AssignmentsController中执行类似的操作(希望它不用说,但是:这些都是未经测试的,如果您只是复制 - 并且不会起作用 - 粘贴):

def new
  @classroom = Classroom.find(params[:id])
  @assignment = @classroom.assignments.new
  @assignment.build_grades_for_classroom_students
end

def create
  classroom = Classroom.find(params[:id])
  assignment = classroom.assignments.build(params[:assignment])
  # ...
  assignment.save!
end

在您看来,这样的事情:

<%= form_for [@classroom, @assignment] do |f_a| %>
  <%= f_a.label :name %>
  <%= f_a.text_field :name %>

  <%= f_a.fields_for :grades do |f_g| %>
    <%= f_g.label :score do %>
      Grade for <%= f_g.object.student.name %>
    <% end %>
    <%= f_g.text_field :score %>
  <% end %>
  <%= f_a.submit %>
<% end %>

(因为我从来没有使用它,所以留给你的是茧宝石。)

这很有消化意义,我敢肯定,但我希望它有所帮助。