【问题标题】:Sorting users by score - rails按分数对用户进行排序 - rails
【发布时间】:2014-04-17 20:28:03
【问题描述】:

在我的 rails 应用程序中,每个用户都有一个业力/分数,我通过用户模型计算如下:

after_invitation_accepted :increment_score_of_inviter

def increment_score_of_inviter
  invitation_by.increment!(:score, 10)
end

def comment_vote_count
  Vote.find(comment_ids).count * 2
end

def calculated_vote_count
  base_score + comment_vote_count
end

def recalculate_score!
  update_attribute(:score, calculated_vote_count)
end

我正在尝试创建所有用户的分页列表,按他们的分数排序。有成千上万的用户,我该如何有效地做到这一点?

我正在考虑使用:

User.all.sort_by(&:calculated_vote_count)

但是,这会很重。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    嗯...在一个充满记录的表上使用User.all 将占用您的应用程序的内存。相反,您应该尝试在 DB 层上完成您想要的。

    此时我假设base_score 是表列之一(base_score 是否与score 相同?),因此您必须执行以下操作(使用 LEFT JOIN):

    User.select("users.*, (COUNT(votes.id) * 2 + users.base_score) AS calculated_vote_count").joins("LEFT JOIN votes ON votes.user_id = user.id").order("calculated_vote_count DESC")
    

    然后你可以按照你喜欢的方式对结果进行分页。

    我没有测试它,但它应该可以工作。如果没有,请告诉我。

    【讨论】:

    • 但是已经有一个vote 列,对吗?您不想在订购用户时进行计算。您应该将分数缓存在某个地方,这是肯定的。
    • Robin,检查他的代码示例中的方法comment_vote_count。不幸的是,他没有vote 专栏。投票在不同的表中计算。这就是我提出使用 JOIN 的原因。理想情况下,他可能正在缓存和/或他甚至可能使用触发器来增加users 表中的votes 列。
    • 但是他不想按 vote_count 排序,他想按分数排序,还是我错过了什么?但是他更新分数列是另一回事,但有一个 score 列,这就是他应该用来为他的用户排序的内容。
    • 正如他在上面的例子中提到的,他正在尝试按calculated_vote_count 方法排序,该方法引用了comment_vote_count 方法,该方法通过Vote 模型计算votes 表中的票数对于给定的用户。如您所见,所有这些逻辑都是我在上面的解决方案中试图转换为 SQL 的。别怪我,怪题主的逻辑。 ;)
    • 我没有责怪任何人 ;) 我正在努力帮助他。他说I'm trying to create paginated list of all the users, sorted by their scores。我猜他的代码可能是错误的,而不是他真正想要做的事情。
    【解决方案2】:

    这很简单:

    User.order('score DESC').all
    

    显然你会有分页,User.order('score DESC').page(params[:page]).per(20) 和 Kaminari。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 2021-03-28
      相关资源
      最近更新 更多