2013-02-01 61 views
0

我想寫一個方法,迄今爲止失敗。找到每個用戶提交的最高分

我有三個型號交互:用戶,提交和分數

分數有submission_id,提交有USER_ID。

用戶提交1-5個提交的任何地方,然後他們收到每個提交的評分。現在我需要爲每個用戶找到所有提交的最高分數。

例如,如果用戶1提交了2張照片,第一次提交得分爲25,第二次提交得分爲50,那麼我需要該方法爲該用戶返回50。

我需要提高我的技能,當談到陣列和範圍,但這裏是快速響應我的團隊成員之一傳遞給我之前,他跑出了門:

「的方式我會做它將覆蓋所有提交內容,並將每個內容存儲在一個散列中,其中的關鍵字是user_id,值是一個包含分數的數組。因此,如果您對同一個user_id有2+個提交,它將指向一組分數。你有散列,只需遍歷數組中的每個元素並選擇最高分,然後將分數存儲在另一個散列中,但是這次分數是關鍵,值是具有該分數的所有user_id的數組。 「

如果你能幫助我,我會非常感激。我不是懶惰的,只是筋疲力盡,我不能再思考了。

下面是相關信息:

用戶模型:

class User < ActiveRecord::Base 
    has_many :submissions, :dependent => :destroy 
end 

提交模型:

class Submission < ActiveRecord::Base 
    attr_accessible :contest_id, :description, :title, :user_id, :video, :image_attributes, 
        :comment_show 
    default_scope order: 'submissions.created_at DESC' 
    belongs_to :user 
    has_one :score, :dependent => :destroy 
end 

分數模型:

class Score < ActiveRecord::Base 
    attr_accessible :effort, :innovation, :passion, :photo_contest_1, :reputation, 
        :scorable_id, :scorable_type, :technical, :uniqueness, :submission_id, 
        :sub_total 

    belongs_to :submission 
end 

[編輯]

所以,我使用的應用程序控制器helper_method :contest_score,像這樣:

def contest_score 
    User.joins(submissions: :score).maximum(:sub_total, group: 'users.id') 
end 

或者:

def contest_score 
    hashed_scores = Submission.joins(:score) 
         .select('max(scores.sub_total) as max_score, submissions.user_id as user_id') 
         .group('submissions.user_id') 
         .map { |subm| Hash[subm.user_id, subm.max_score] } 
         .reduce(&:merge) 
end 

然後,我呈現在用戶顯示模板,因爲每個成員高分在比賽中:

<%= contest_score %> contest points<br/> 

回答

1

這應該做的伎倆

scores = User.joins(submissions: :score).maximum(:sub_total, group: 'users.id') 

這將導致以等於user_id鍵的哈希,並等於最高比分淘汰所有提交的值。

UPDATE:無需從User

Score.joins(:submission).maximum(:sub_total, group: 'submissions.user_id') 
+0

嘗試排名第一併獲得相同的兩個值:{6565 =>「15」,4968 =>「7」}。最高分是100,所以也許有些東西我沒有提供,信息明智。讓我通過增加一個附錄來修改這個問題。 –

+0

@BrianMcDonough是具有實際分數的列的sub_total? –

+0

是的。 sub_total是唯一重要的分數。 –

1

我相信你可以做到這一點。它將使用一個查詢併爲您提供所需的數據。

hashed_scores = Submission.joins(:score) 
          .select('max(scores.sub_total) as max_score, submissions.user_id as user_id') 
          .group('submissions.user_id') 
          .map { |subm| Hash[subm.user_id, subm.max_score] } 
          .reduce(&:merge) 

這應該是遠更高效那麼你的解決方案,因爲它僅訪問數據庫一次,也是沒有必要的分數排序,只選擇那些最大,因爲數據庫能爲你做到這一點。

+0

好走,我改變了:得分

這裏是如何得到的結果由得分最高

scores.inject({}) do |hash, (user_id, score)| hash[score] ||= [] hash[score] << user_id hash end 

UPDATE加入:評分,然後得到這個錯誤:'PG ::錯誤:錯誤:列「submissions.created_at」必須出現在GROUP BY子句中或用於聚合函數中# –

+1

現在就試試它有一個缺少一個'do'。 –

+1

哦!那是因爲你可能有一個默認範圍。 –

相關問題