从提交中查找每个用户的最高分数

时间:2013-02-01 01:20:13

标签: ruby-on-rails ruby arrays

我正在尝试编写一个方法,到目前为止还没有成功。

我有三个模型互动:用户,提交和分数

分数有submission_id,提交有user_id。

用户提交1-5份提交的任何地方,然后他们就每份提交的内容得到了分数。现在我需要找到每个用户的所有提交的最高分。

例如,如果用户1提交了2张照片并且第一次提交得分为25而第二次提交得分为50,那么我需要该方法为该用户返回50.

在数组和范围方面,我需要提高自己的技能,但这是我的团队成员在他跑出大门之前传递给我的快速反应:

“我会这样做的方法是遍历所有提交并将每个存储在一个哈希中,其中键是user_id,值是一个带有分数的数组。所以如果你有2个以上的提交给同一个user_id,它将指向一个分数数组。一旦你有了哈希,只需遍历数组的每个元素并选择最高分。然后你将分数存储在另一个哈希中,但这次分数是关键,值是带有该分数的所有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/>

2 个答案:

答案 0 :(得分: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)

这应该比你的解决方案更有效率,因为它只能访问数据库一次,而且不需要对分数进行排序,只选择最大分数,因为数据库可以为你做。

答案 1 :(得分:1)

这应该可以解决问题

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

这将导致哈希的密钥等于user_id,其值等于所有提交的最高分。

更新:

以下是如何以最高分数加入结果

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

更新:无需离开User

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