game_typeを持つゲームでゲームをプレイするためのポイントをユーザーに提供するアプリがあります。私がしたいことは次のとおりです。
- ゲームに基づいてポイントを小計する
- 他のユーザーと比較したgame_idのポイント数に基づいて、ユーザーのゲームランク(ランク1 =最も多くのポイント)を決定します
- game_typeに基づいてポイントを小計する
- 他のユーザーと比較したgame_type_idのポイント数に基づいて、ユーザーのgame_typeランク(ランク1 =ほとんどのポイント)を決定します
上記のクエリ結果に基づいて、game_typesとgamesの間の上位5ポイントのランキングのみを表示したいと思います。
たとえば、ユーザーの計算が次のようになっているとします。
game_id = 1, rank 200
game_id = 2, rank 10
game_id = 3, rank 6
game_id = 4, rank 31
game_type_id = 1, rank 500
game_type_id = 2, rank 400
game_type_id = 3, rank 1
game_type_id = 4, rank 7
game_type_id = 5, rank 100
次に、games:2、3、4およびgame_types:3、4、5のランクのみを表示したいと思います。これらは、このユーザーのゲームおよびgame_typesの上位5つのランクであるためです。
ユーザーテーブルにgame_typeとgame(game_1_rank、game_2_rank、game_type_1_rankなど)ごとにgame_typeとgameフィールドを作成して、バックグラウンドジョブのポイントを1時間ごとに計算し、から最高ランクを取得しようと考えました。そこにありますが、新しいゲームとgame_typesが時間の経過とともに追加されているため、これが最善のアプローチではないと思います。
したがって、users#showページが読み込まれたときに計算を行い、そのページをキャッシュする(そして1時間ごとに期限切れになる)のが最善の方法だと考えていました。
私のモデルは次のようになります。
user
has_many :points
point
belongs_to :game
belongs_to :game_type
belongs_to :user
game
has_many :points
has_one :game_type
game_type
has_many :points
すべてのゲームとgame_typesの全体的なランキングを計算するために、Users#showにこのコードがありますが、ビューのトップランクにアクセスできるように調整する方法がわかりません(ビューにコードはまだありません)このユーザーの上位5ランクと、そのユーザーの対象となるゲーム/ game_typesを表示します)。
# calculate ranks for all users for all games in order to find the user's rank
@games = Game.all
@games.each do |game|
@users_by_game = Point.where(“game_id = ?”, game.id).select("sum(amount) as points, user_id").order("points desc").group("user_id")
rank = 0
points = 0
@users_by_game.each_with_index do |user_by_game, index|
if user_by_game.points != points
points = user_by_game.points
rank += 1
end
end
# calculate ranks for all users for all games_types in order to find the user's rank
@game_types = GameType.all
@game_types.each do |game_type|
@users_by_game_type = Point.where(“game_type_id = ?”, game_type.id).select("sum(amount) as points, user_id").order("points desc").group("user_id")
rank = 0
points = 0
@users_by_game_type.each_with_index do |user_by_game_type, index|
if user_by_game_type.points != points
points = user_by_game_type.points
rank += 1
end
end
end
私が決定しようとしているのは:
- これは、これらのランクを計算するための最良のアプローチですか、それともよりリソース効率の高い、またはDRYの方法がありますか?
- これが最善の方法である場合、コードはすべてのユーザーのランクのみを計算しているため、コードとビューを変更して、この@userの上位5つのgame / game_typeランキングを表示するにはどうすればよいですか?