0

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

我有三个交互的模型:用户、提交和分数

score有submission_id,submission有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在应用程序控制器中使用 a ,如下所示:

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/>
4

2 回答 2

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)

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

于 2013-02-01T01:42:26.523 回答
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')
于 2013-02-01T02:01:44.280 回答