Skip to content

Commit dc05cc0

Browse files
committed
Fix SubmissionPolicy::DeadlineScope to account for deadlines correctly
Previously, the `DISTINCT ON` projection was applied before any scope. However, if only one submission per learner and exercise is returned, the scope will only filter the results further. Desired is a behavior where only those submissions matching the given scoped are used for the DISTINCT ON clause.
1 parent 2bf1d29 commit dc05cc0

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

app/policies/submission_policy.rb

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ def resolve
5959
resolved_scope = super
6060
return resolved_scope unless @user.teacher?
6161

62-
latest_before_deadline = latest_submissions_assessed.before_deadline.arel
63-
latest_within_grace_period = latest_submissions_assessed.within_grace_period.arel
64-
latest_after_late_deadline = latest_submissions_assessed.after_late_deadline.arel
65-
highest_before_deadline = latest_submissions_assessed(highest_scored: true).before_deadline.arel
66-
highest_within_grace_period = latest_submissions_assessed(highest_scored: true).within_grace_period.arel
67-
highest_after_late_deadline = latest_submissions_assessed(highest_scored: true).after_late_deadline.arel
62+
latest_before_deadline = latest_submissions_assessed(scope: :before_deadline).arel
63+
latest_within_grace_period = latest_submissions_assessed(scope: :within_grace_period).arel
64+
latest_after_late_deadline = latest_submissions_assessed(scope: :after_late_deadline).arel
65+
highest_before_deadline = latest_submissions_assessed(scope: :before_deadline, highest_scored: true).arel
66+
highest_within_grace_period = latest_submissions_assessed(scope: :within_grace_period, highest_scored: true).arel
67+
highest_after_late_deadline = latest_submissions_assessed(scope: :after_late_deadline, highest_scored: true).arel
6868

6969
# Yes, we construct a huge union of seven relations: all three deadlines, all three highest scores and the resolved scope
7070
all_unions = construct_union(
@@ -86,9 +86,13 @@ def resolve
8686

8787
# This method is used to get the latest submission that was assessed or remote assessed.
8888
# By default, it will simply return the one with the last time stamp per exercise and contributor.
89-
# However, with the optional parameter, the highest scored submission that was scored the latest will be returned.
90-
def latest_submissions_assessed(highest_scored: false)
89+
# There are two optional parameters:
90+
# - `scope` can be set to filter the submissions using a predefined scope (as defined in the Submission model).
91+
# - `highest_scored` can be set to get the *highest-scored* submission that was scored the latest.
92+
# Otherwise, the submission with the latest time stamp will be returned (independent of the score).
93+
def latest_submissions_assessed(scope: nil, highest_scored: false)
9194
submission_table = Submission.arel_table
95+
scoped_submissions = scope.present? ? Submission.public_send(scope).arel : submission_table
9296

9397
desired_table_order = [
9498
submission_table[:exercise_id],
@@ -99,9 +103,8 @@ def latest_submissions_assessed(highest_scored: false)
99103
].compact
100104

101105
Submission.from(
102-
submission_table.project(
103-
Arel.sql('DISTINCT ON (submissions.exercise_id, submissions.contributor_type, submissions.contributor_id) submissions.*')
104-
)
106+
scoped_submissions
107+
.distinct_on([submission_table[:exercise_id], submission_table[:contributor_type], submission_table[:contributor_id]])
105108
.order(*desired_table_order)
106109
.where(submission_table[:cause].in(%w[assess remoteAssess]))
107110
.where(submission_table[:study_group_id].in(@user.study_group_ids_as_teacher))

0 commit comments

Comments
 (0)