Skip to content

Commit c5467ca

Browse files
authored
Fix leaderboard XP computation logic and improve query code (#1292)
* Fix leaderboard XP calculation * Convert count query to use pipelines * Use pipeline query for total xp * Fix results of leaderboard xp query returning as decimal * Use direct map on result instead
1 parent 160de6d commit c5467ca

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

lib/cadet/assessments/assessments.ex

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -240,28 +240,31 @@ defmodule Cadet.Assessments do
240240
user_id: u.id,
241241
submission_xp: sum(a.xp) + sum(a.xp_adjustment) + max(s.xp_bonus)
242242
})
243+
|> subquery()
244+
|> group_by([t], t.user_id)
245+
|> select([t], %{
246+
user_id: t.user_id,
247+
submission_xp: sum(t.submission_xp)
248+
})
243249

244250
total_xp_query =
245-
from(cu in subquery(course_userid_query),
246-
inner_join: u in User,
247-
on: u.id == cu.id,
248-
left_join: ax in subquery(achievements_xp_query),
249-
on: u.id == ax.user_id,
250-
left_join: sx in subquery(submissions_xp_query),
251-
on: u.id == sx.user_id,
252-
select: %{
253-
user_id: u.id,
254-
name: u.name,
255-
username: u.username,
256-
total_xp:
257-
fragment(
258-
"COALESCE(?, 0) + COALESCE(?, 0)",
259-
ax.achievements_xp,
260-
sx.submission_xp
261-
)
262-
},
263-
order_by: [desc: fragment("total_xp")]
264-
)
251+
course_userid_query
252+
|> subquery()
253+
|> join(:inner, [cu], u in User, on: cu.id == u.id)
254+
|> join(:left, [cu, _], ax in subquery(achievements_xp_query), on: cu.id == ax.user_id)
255+
|> join(:left, [cu, _, _], sx in subquery(submissions_xp_query), on: cu.id == sx.user_id)
256+
|> select([_, u, ax, sx], %{
257+
user_id: u.id,
258+
name: u.name,
259+
username: u.username,
260+
total_xp:
261+
fragment(
262+
"COALESCE(?, 0) + COALESCE(?, 0)",
263+
ax.achievements_xp,
264+
sx.submission_xp
265+
)
266+
})
267+
|> order_by(desc: fragment("total_xp"))
265268

266269
# add rank index
267270
ranked_xp_query =
@@ -274,13 +277,17 @@ defmodule Cadet.Assessments do
274277
)
275278

276279
count_query =
277-
from(t in subquery(total_xp_query),
278-
select: count(t.user_id)
279-
)
280+
total_xp_query
281+
|> subquery()
282+
|> select([t], count(t.user_id))
280283

281284
{status, {rows, total_count}} =
282285
Repo.transaction(fn ->
283-
users = Repo.all(ranked_xp_query)
286+
users =
287+
Enum.map(Repo.all(ranked_xp_query), fn user ->
288+
%{user | total_xp: Decimal.to_integer(user.total_xp)}
289+
end)
290+
284291
count = Repo.one(count_query)
285292
{users, count}
286293
end)

0 commit comments

Comments
 (0)