2011-07-12 1 views
0

「テスト」を受けた学生は5つの質問があります。私がしたいことは、各テストの各質問について最大のスコアを示すことです。Rubyはテーブルの属性を持つcollect/mapを使用します

Test、Student、Questionはすべて別のテーブルです。私が持っている

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 

それは私が各テストの各質問のための最大のスコアを印刷したい5に各「question_number」1の最大を返しません。質問表で

例)

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 'という名前の列があります。私はこの属性を使って私が望む結果を得る方法を知らない。

+0

あなたが他のループをしたい私には思えるし、質問の数を出力するすべての質問のオブジェクトの上に横断し、スコア属性あなたが今説明する方法では、maxメソッドを全く使用したくはありません。 – Maran

+0

私の答えをチェックしてください。あなたが完全に間違っている収集を持っていることにも注意してください、それは必須ではありません(googleで '機能的なルビー'を検索してください) – tokland

答えて

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>が出力されます。あなたはそれぞれの質問に対して一度それをしたいです。より良い解決策はスコープを書くことです。線に沿って何か:

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 %> 
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 %> 
+0

答えをありがとう。私はそれがどのように変わることができるかを知っています。しかし、現時点では構造を変更する方法はありません。 –

関連する問題