Skip to content

Commit d862a0b

Browse files
committed
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 46b1292 commit d862a0b

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
@@ -202,28 +202,31 @@ defmodule Cadet.Assessments do
202202
user_id: u.id,
203203
submission_xp: sum(a.xp) + sum(a.xp_adjustment) + max(s.xp_bonus)
204204
})
205+
|> subquery()
206+
|> group_by([t], t.user_id)
207+
|> select([t], %{
208+
user_id: t.user_id,
209+
submission_xp: sum(t.submission_xp)
210+
})
205211

206212
total_xp_query =
207-
from(cu in subquery(course_userid_query),
208-
inner_join: u in User,
209-
on: u.id == cu.id,
210-
left_join: ax in subquery(achievements_xp_query),
211-
on: u.id == ax.user_id,
212-
left_join: sx in subquery(submissions_xp_query),
213-
on: u.id == sx.user_id,
214-
select: %{
215-
user_id: u.id,
216-
name: u.name,
217-
username: u.username,
218-
total_xp:
219-
fragment(
220-
"COALESCE(?, 0) + COALESCE(?, 0)",
221-
ax.achievements_xp,
222-
sx.submission_xp
223-
)
224-
},
225-
order_by: [desc: fragment("total_xp")]
226-
)
213+
course_userid_query
214+
|> subquery()
215+
|> join(:inner, [cu], u in User, on: cu.id == u.id)
216+
|> join(:left, [cu, _], ax in subquery(achievements_xp_query), on: cu.id == ax.user_id)
217+
|> join(:left, [cu, _, _], sx in subquery(submissions_xp_query), on: cu.id == sx.user_id)
218+
|> select([_, u, ax, sx], %{
219+
user_id: u.id,
220+
name: u.name,
221+
username: u.username,
222+
total_xp:
223+
fragment(
224+
"COALESCE(?, 0) + COALESCE(?, 0)",
225+
ax.achievements_xp,
226+
sx.submission_xp
227+
)
228+
})
229+
|> order_by(desc: fragment("total_xp"))
227230

228231
# add rank index
229232
ranked_xp_query =
@@ -236,13 +239,17 @@ defmodule Cadet.Assessments do
236239
)
237240

238241
count_query =
239-
from(t in subquery(total_xp_query),
240-
select: count(t.user_id)
241-
)
242+
total_xp_query
243+
|> subquery()
244+
|> select([t], count(t.user_id))
242245

243246
{status, {rows, total_count}} =
244247
Repo.transaction(fn ->
245-
users = Repo.all(ranked_xp_query)
248+
users =
249+
Enum.map(Repo.all(ranked_xp_query), fn user ->
250+
%{user | total_xp: Decimal.to_integer(user.total_xp)}
251+
end)
252+
246253
count = Repo.one(count_query)
247254
{users, count}
248255
end)

0 commit comments

Comments
 (0)