feat: instructors can appear as graders#8060
Conversation
Coverage Report for CI Build 29963024176Coverage increased (+0.02%) to 90.429%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats💛 - Coveralls |
| # is a list of grouping IDs involved in the unassignment. The memberships | ||
| # and groupings must belong to the given assignment +assignment+. | ||
| def self.unassign_tas(ta_membership_ids, grouping_ids, assignment) | ||
| grouping_ids = assignment.groupings.where(id: grouping_ids).ids |
There was a problem hiding this comment.
This is a separate bug unrelated to the current task. It's good to fix, but please do so in a separate PR.
| ta_ids = Ta.where(id: ta_ids).ids | ||
| grouping_ids = Grouping.where(id: grouping_ids).ids | ||
| ta_ids = assignment.course.graders.where(id: ta_ids).ids | ||
| grouping_ids = assignment.groupings.where(id: grouping_ids).ids |
There was a problem hiding this comment.
This is a separate bug unrelated to the current task. It's good to fix, but please do so in a separate PR.
| has_many :roles | ||
| has_many :instructors | ||
| has_many :tas | ||
| has_many :graders, -> { where(type: %w[Instructor Ta]) }, class_name: 'Role', inverse_of: :course |
There was a problem hiding this comment.
Naming here is quite challenging. The current application uses "TAs" and "Graders" as somewhat synonymous, both internally and externally. That's not ideal, but some historical baggage we have to live with now.
Please rename this association to course_staff. It's in some sense more generic (not specifically about grading) but has a fairly intuitive meaning.
Carry this renaming throughout; for example, rename GraderRole to CourseStaffRole
| ta_ids.each_with_index do |group, index| | ||
| weightings[group] = (weightings_arr[index].to_f / total * grouping_ids.length).round | ||
| end | ||
| weightings = Array(ta_ids).map(&:to_i).zip(weightings_arr).to_h |
There was a problem hiding this comment.
The changes in this method are unrelated to the current task, and (unlike the ones below) I do not see what problem this is trying to solve. Revert these changes and message me separately about this method.
| if role && !role.is_a?(Ta) | ||
| errors.add(:base, :not_ta) | ||
| def must_be_a_grader | ||
| if role && !role.is_a?(Ta) && !role.instance_of?(Instructor) |
There was a problem hiding this comment.
Similar to my above comment, use is_a?
| # rubocop:enable Layout/LineLength, Lint/RedundantCopDisableDirective | ||
| class TaMembership < Membership | ||
| validate :must_be_a_ta | ||
| validate :must_be_a_grader |
There was a problem hiding this comment.
Rename to must_be_course_staff
| models: | ||
| ta_membership: | ||
| not_ta: User must be a TA | ||
| not_grader: User must be a TA or instructor |
There was a problem hiding this comment.
rename this key to not_course_staff
| ## Graders Tab | ||
|
|
||
| The graders tab can be used to assign graders to specific students. Once you assign a grader to a student, they will be able to perform all the same actions as the instructor account (including releasing marks). However, they may only perform these actions on students that have been assigned to them. | ||
| The Graders tab can be used to assign graders to specific student groups and marking criteria. For assignments, both course graders and course instructors are available for assignment. Assigning an instructor can be useful for distributing and tracking marking work, but does not restrict the access they already have as an instructor. |
There was a problem hiding this comment.
"course graders" -> "course TAs"
| The graders tab can be used to assign graders to specific students. Once you assign a grader to a student, they will be able to perform all the same actions as the instructor account (including releasing marks). However, they may only perform these actions on students that have been assigned to them. | ||
| The Graders tab can be used to assign graders to specific student groups and marking criteria. For assignments, both course graders and course instructors are available for assignment. Assigning an instructor can be useful for distributing and tracking marking work, but does not restrict the access they already have as an instructor. | ||
|
|
||
| For marks spreadsheets, graders can be assigned to individual students, but instructors are not included as assignable graders. |
There was a problem hiding this comment.
Please make this an inset "NOTE" (see how we do this elsewhere in the docs). Also, replace "graders" with "TAs"
| ### Table Info | ||
|
|
||
| When you arrive at the "Manage Graders" page you will see a table of graders: | ||
| When you arrive at the "Manage Graders" page you will see a table of assignable graders. For assignments, this table contains both graders and instructors: |
There was a problem hiding this comment.
"graders and instructors" -> "TAs and instructors"
| ## Setting up a Grader Account | ||
|
|
||
| If anyone other than the course instructor wants to be able to grade a student (or group's) work, they must have a "Grader" account. This means if a course has 4 TAs and everyone wants to be able to grade work, you must set up 4 separate "Grader" accounts - one for each TA. The course instructor does not require a separate account for grading as all marking can also be done from the admin account. | ||
| Anyone other than a course instructor who needs to grade student work must have a "Grader" account. For example, if a course has 4 TAs who will all grade work, you must set up 4 separate Grader accounts—one for each TA. |
There was a problem hiding this comment.
"Grader" account -> "TA" account (and same for "Grader accounts")
| has_one :course, through: :assignment | ||
|
|
||
| validate :courses_should_match | ||
| validate :must_be_a_grader |
There was a problem hiding this comment.
rename to must_be_course_staff
| course_tas = assignment.course.tas | ||
| unless ta_user_names.all? { |g| course_tas.joins(:user).exists?('users.user_name': g) } | ||
| course_staff = assignment.course.course_staff | ||
| unless ta_user_names.all? { |g| course_staff.joins(:user).exists?('users.user_name': g) } |
There was a problem hiding this comment.
please rename ta_user_names to staff_user_names
| private | ||
|
|
||
| def must_be_course_staff | ||
| errors.add(:ta, :invalid) if ta && !ta.is_a?(Ta) && !ta.is_a?(Instructor) |
There was a problem hiding this comment.
I'm sorry, I forgot that AdminRole is a subclass of Instructor. We don't want "admins" to be assigned to be graders. Please revert to instance_of? and the additional tests. But also leave a comment explaining that we use instance_of? to exclude AdminRole.
david-yz-liu
left a comment
There was a problem hiding this comment.
Nice work, @YheChen!
Proposed Changes
(Describe your changes here. Also describe the motivation for your changes: what problem do they solve, or how do they improve the application or codebase? If this pull request fixes an open issue, use a keyword to link this pull request to the issue.)
This PR allows course instructors to be assigned as graders for assignments, alongside TAs.
This is the first incremental part of #1221.
Ref #1221
Screenshots of your changes (if applicable)
Type of Change
(Write an
Xor a brief description next to the type or types that best describe your changes.)Checklist
(Complete each of the following items for your pull request. Indicate that you have completed an item by changing the
[ ]into a[x]in the raw text, or by clicking on the checkbox in the rendered description on GitHub.)Before opening your pull request:
After opening your pull request:
Questions and Comments
(Include any questions or comments you have regarding your changes.)