0

私には、5つの「質問」がある「テスト」を受けた学生がいます。私がやりたいのは、各テストの各質問の最大「スコア」を表示することです。

テスト、学生、質問はすべて別々のテーブルです。

class Test < ActiveRecord::Base
  has_many :students
end

class Student < ActiveRecord::Base
  belongs_to :test
  has_many :questions
end

class Question < ActiveRecord::Base
  belongs_to :students
end

私が持っているコード:

<% @tests.each do |test| %>
<% max_score = [] %>
    <% test.students.collect {|s| s.questions.collect {|q| max_score << q.score}}%>

    <tr>
      <th><%= test.name %></th>
      <th><%= max_score.max %></th
    </tr>
<% end %>

ただし、これが示すのは、テスト全体の最大スコアです。

例)

Math - 95
History - 98
Physics - 100

'question_number' 1〜5ごとの最大値は返されません。各テストの各質問の最大スコアを出力したいと思います。

例)

Math - 1 - 90
Math - 2 - 100
Math - 3 - 88
Math - 4 - 79
Math - 5 - 98
History - 1 - 80
History - 2 - 95
..and so on...

質問テーブルには、「question_number」という名前の列があります。この属性を使用して希望の結果を得る方法がわかりません。

4

2 に答える 2

3

モデルが間違っています。これで遊んでください:

class Test < ActiveRecord::Base
  has_many :questions
end

class Question < ActiveRecord::Base
  belongs_to :test
  has_many :question_scores
  has_many :students, :through => :question_scores
end

class Student < ActiveRecord::Base
  has_many :question_scores
  has_many :questions, :through => :question_scores
end

class QuestionScore < ActiveRecord::Base
  belongs_to :student
  belongs_to :question
end

そして、コードは次のようになります。

<% @tests.each do |test| %>
  <% test.questions.each do |question| %>
    test: <% test.name %>
    question: <%= question.name %>
    max score: <%= question.question_scores.maximum(:score) %>
  <% end %>
<% end %>
于 2011-07-12T20:53:10.590 に答える
0

コメントが示すように、クラス構造を変更できない場合は、少し醜いものになります。あなたはまだhas_many :through少し物事をきれいにするために追加することができます:

class Test < ActiveRecord::Base
  has_many :students
  has_many :questions, :through => :students
end

class Student < ActiveRecord::Base
  belongs_to :test
  has_many :questions
end

class Question < ActiveRecord::Base
  belongs_to :students
end

次に、イテレータをネストする必要があります...

<% @tests.each do |test| %>
  <% 1.upto(5) do |index|
    max = test.questions.select {|q| 
            q.question_number == index }.max_by {|q| q.score } %>
    <tr>
      <td><%= test.name %></td>
      <td><%= index %></td>
      <td><%= max.score %></td>
    </tr>
  <% end %>
<% end %>

現状のコードの問題の1つは、<tr>テストごとに1回しか出力しないことです。質問ごとに1回実行します。より良い解決策は、スコープを作成することです。次のようなもの:

class Test < ActiveRecord::Base
  has_many :students
  has_many :questions, :through => :students
end

class Student < ActiveRecord::Base
  belongs_to :test
  has_many :questions
end

class Question < ActiveRecord::Base
  belongs_to :student

  scope :max_score_by_question_number, lambda {|num| where(:question_number => num).maximum(:score) }
end

次に、これを行うことができます。

<% @tests.each do |test| %>
  <% 1.upto(5) do |index|
    max = test.questions.max_score_by_question_number(index) %>
      <tr>
        <td><%= test.name %></td>
        <td><%= index %></td>
        <td><%= max.score %></td>
      </tr>
    <% end %>
  <% end %>
于 2011-07-13T06:04:56.793 に答える