ruby-on-rails - 分组后如何在 Rails 中排名
问题描述
在我使用 Postgres 的 Rails 6 应用程序中,我有一个名为UserCategories
.
| id | user_id | category_id | points| rank |
我想做的是:
- 按 category_id 对记录进行分组
- 按点对每个 category_id 的记录进行排序 (desc)
- 根据 category_id 的记录顺序更新排名字段
示例(由每个 category_id 的点数确定的所需排名):
| id | user_id | category_id | points| rank |
| 1 | 1 | 1 | 2 | | # I want rank to be 1
| 2 | 2 | 1 | 1 | | # I want rank to be 2
| 3 | 1 | 2 | 3 | | # I want rank to be 1
| 4 | 2 | 2 | 3 | | # I want rank to be 1
我的模型方法:
def self.calculate_user_category_ranks
@user_categories = UserCategory.select(:id, :points, :user_id, :category_id, :rank).all.order(points: :desc).group_by(&:category_id)
# returns:
# {2=>[#<UserCategory:0x000000000de8be00 id: 2, user_id: 1, category_id: 2, points: 3, rank: 0>, #<UserLeague:0x000000000de8bce8 id: 4, user_id: 2, category_id: 2, points: 3, rank: 0>],
1=>[#<UserCategory:0x000000000de8bbf8 id: 1, user_id: 1, category_id: 1, points: 2, rank: 0>, <UserLeague:0x000000000de8bb30 id: 3, user_id: 2, category_id: 1, points: 1, rank: 0>]}
rank = 0
points_counter = 0
@user_categories.each do |id, points|
uc = UserCategory.find(id)
if points != point_counter
rank += 1
point_counter = points
end
uc.rank = rank
uc.save
end
end
执行此代码后:
| id | user_id | category_id | points| rank |
| 1 | 1 | 1 | 2 | 2 | # I want rank to be 1
| 2 | 2 | 1 | 1 | 0 | # I want rank to be 2
| 3 | 1 | 2 | 3 | 1 | # I want rank to be 1
| 4 | 2 | 2 | 3 | 0 | # I want rank to be 1
有人可以帮我确定我做错了什么吗?
解决方案
出于效率的原因,您可能选择将rank
其作为数据库列,但数据库规范化的原则表明,拥有一个可以从表中的其他列计算出其值的列是“不好的做法”。因此,认识到出于效率原因您可能不接受此解决方案,让我建议,对于您的任何特定实例,UserCategory
您都可以确定其在 Ruby 中的排名:
class UserCategory < ApplicationRecord
scope :in_the_same_category, ->(category_id) { where("category_id = ?", category_id }
def in_my_category
UserCategory.in_the_same_category(category_id)
end
def rank
in_my_category.
sort_by(&:points).
reverse.
map(&:points).
uniq.
index(points) + 1
end
end
推荐阅读
- java - 读取返回 StreamingResponseBody 作为响应的 API
- html - how do I compare textarea enter character
- python - tf 的示例。group_by_reducer?
- ios - 具有大型数据集的 NSPersistentContainer 和 NSFetchedResultsController
- javascript - 路由到 Angular 应用程序中的另一个组件后,外部脚本不会加载
- python-3.x - 估计器最终导出的克隆模型步骤中的尺寸不匹配
- java - zalenium java空指针异常
- mysql - SQL:从另一个查询中减去一个查询
- android - 使用 Mvvm 方法处理分页库中的错误
- reactjs - React TypeError:onGenreChange 不是函数