canvas-lms/app/models/rubric_assessment.rb

245 lines
8.4 KiB
Ruby
Raw Normal View History

2011-02-01 09:57:29 +08:00
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Associates an artifact with a rubric while offering an assessment and
2011-02-01 09:57:29 +08:00
# scoring using the rubric. Assessments are grouped together in one
# RubricAssociation, which may or may not have an association model.
class RubricAssessment < ActiveRecord::Base
include TextHelper
include HtmlTextHelper
2011-02-01 09:57:29 +08:00
attr_accessible :rubric, :rubric_association, :user, :score, :data, :comments, :assessor, :artifact, :assessment_type
belongs_to :rubric
belongs_to :rubric_association
belongs_to :user
belongs_to :assessor, :class_name => 'User'
belongs_to :artifact, :polymorphic => true, :touch => true
validates_inclusion_of :artifact_type, :allow_nil => true, :in => ['Submission', 'Assignment']
2011-02-01 09:57:29 +08:00
has_many :assessment_requests, :dependent => :destroy
serialize :data
2011-02-01 09:57:29 +08:00
simply_versioned
EXPORTABLE_ATTRIBUTES = [:id, :user_id, :rubric_id, :rubric_association_id, :score, :data, :comments, :created_at, :updated_at, :artifact_id, :artifact_type, :assessment_type, :assessor_id, :artifact_attempt]
EXPORTABLE_ASSOCIATIONS = [:rubric, :rubric_association, :user, :assessor, :artifact, :assessment_requests]
validates_presence_of :assessment_type, :rubric_id, :artifact_id, :artifact_type, :assessor_id
2011-02-01 09:57:29 +08:00
validates_length_of :comments, :maximum => maximum_text_length, :allow_nil => true, :allow_blank => true
2011-02-01 09:57:29 +08:00
before_save :update_artifact_parameters
before_save :htmlify_rating_comments
2011-02-01 09:57:29 +08:00
after_save :update_assessment_requests, :update_artifact
after_save :track_outcomes
2011-02-01 09:57:29 +08:00
def track_outcomes
outcome_ids = (self.data || []).map{|r| r[:learning_outcome_id] }.compact.uniq
send_later_if_production(:update_outcomes_for_assessment, outcome_ids) unless outcome_ids.empty?
2011-02-01 09:57:29 +08:00
end
2011-02-01 09:57:29 +08:00
def update_outcomes_for_assessment(outcome_ids=[])
return if outcome_ids.empty?
fix anonymous peer review checkbox on graded discussion form. fixes CNVS-19782 The checkbox used to determine whether or not an assignment's peer reviews should be considered anonymous, which is part of a backbone view, did not function properly if it was 'nested' (i.e., if the name on the field should be `assiginment[anonymous_peer_reviews]`, instead of just `anonymous_peer_reviews`. The `checkbox` helper is already setup to handle this; we just needed to pass the `nested` value to it, and to update how we determine whether or not the checkbox should appear checked, so as to avoid manually setting the checkbox's `name` attribute. Additionally, this patch fixes a bug in the `RubricAssessment#considered_anonymous?` method, which would blow up if the model did not have a related rubric_association. I've added a protection to two other methods that would have thrown exceptions in the absence of a rubric_assocation as well. Finally, I updated the logic in the SubmissionComment policy declaration, so that when trying to `:read_author`, a student can always see the name of a teacher, even if the comment is marked as anonymous. test plan: - as a teacher, create a graded discussion topic. When doing say, enable peer reviews, and enable anonymous peer reviews. - as a student, submit an entry for the graded discussion topic. - as a teacher, assign a peer review to a student for the submission above. - as the reviewer student, submit a review. - as the reviewed student, navigate to the submission details page (/courses/:course_id/assignments/:assignment_id/submissions/:user_id) and observe the comment list on the right hand side of the page. - observe that the name of the reviewer student is not present, and instead it says 'Anonymous User'. - as the teacher, navigate to the same submission page, and observe the comment list on the right hand side of the page. - observe that the name of the reviewer student IS present. - as the teacher, navigate to the same submission page, and observe the comment list on the right hand side of the page - as the teacher, leave a comment on the submitted assignment. - as the reviewed student, navigate to the submission details page, and observe the comment list on the right hand side of the page. - observe that the name of the reviewer teacher IS present. Change-Id: I572dd7fa319cd784e59f00057898fcea5349c899 Reviewed-on: https://gerrit.instructure.com/52099 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-04-14 07:10:02 +08:00
alignments = if self.rubric_association.present?
self.rubric_association.association_object.learning_outcome_alignments.where({
learning_outcome_id: outcome_ids
})
else
[]
end
2011-02-01 09:57:29 +08:00
(self.data || []).each do |rating|
if rating[:learning_outcome_id]
learning outcomes refactor This list is *NOT* complete, some items may have snuck in that I forgot to note, and/or some of the noted items may not be completely functional yet. Specs need to be written around a lot of this, other specs will no doubt need to be fixed. Some things, particularly around LearningOutcomeGroups will need data migrations that aren't there yet. * remove LearningOutcome.non_rubric_outcomes? and replace with false where invoked * remove LearningOutcome.enabled? and replace with true where invoked * remove never-taken branches * remove the shared/aligned_outcomes partial and it's supporting javascript, since it's now empty * remove js handler for add_outcome_alignment_link and supporting method since it only occurred in never-taken branches * mix LearningOutcomeContext into Course and Account * replace LearningOutcomeGroup.default_for(context) with LearningOutcomeContext#root_outcome_group * rename LearningOutcome#content_tags to LearningOutcome#alignments * rename LearningOutcomeGroup#content_tags to LearningOutcomeGroup#child_links, and properly restrict * remove ContentTag[Alignment]#rubric_association_id, add ContentTag[Alignment]#has_rubric_association? that looks at the presence of the content's rubric_association_id * condition off the assignment having a rubric_association rather than filtering tags by has_rubric_association (which just looks back at the assignment). all or none of the assignment's alignments are forced to have the association (via the assignment). this was true in practice before, is now codified (and more efficient) * rename AssessmentQuestionBank#learning_outcome_tags to AssessmentQuestionBank#learning_outcome_alignments * rename Assignment#learning_outcome_tags to Assignment#learning_outcome_alignments * rename Rubric#learning_outcome_tags to Rubric#learning_outcome_alignments * move/rename (Course|Account)#learning_outcome_tags to LearningOutcomeContext#learning_outcome_links * move/rename Account#learning_outcomes (corrected) and Course#learning_outcomes to LearningOutcomeContext#linked_learning_outcomes * move/rename Account#created_learning_outcomes and Course#created_learning_outcomes to LearningOutcomeContext#created_learning_outcomes * clarify and correct usage of linked_learning_outcomes vs. created_learning_outcomes * move/rename (Account|Account)#learning_outcome_groups to LearningOutcomeContext#learning_outcome_groups * remove unused Account#associated_learning_outcomes * just remove one link to a learning outcome when deleting * merge Account#has_outcomes?, Course#has_outcomes? and Course#has_outcomes into LearningOutcomeContext#has_outcomes?, add a use in Context#active_record_types * kill LearningOutcomeGroup#root_learning_outcome_group (unused) * rename LearningOutcomeResult#content_tag to LearningOutcomeResult#alignment * kill unused (and broken) OutcomesController#add_outcome_group * kill unused OutcomesController#update_outcomes_for_asset * kill unused OutcomesController#outcomes_for_asset * remove unused (outside specs, correct specs) AssessmentQuestionBank#outcomes= * remove unused ContentTag#learning_outcome_content * replace ContentTag.learning_outcome_tags_for(asset) (only ever called with asset=an assignment) with call to Assignment#learning_outcome_alignments * remove unused ContentTag.not_rubric * remove (now) unused ContentTag.include_outcome * remove unused LearningOutcome#learning_outcome_group_associations * avoid explicit use of ContentTag in outcome-related specs * replace LearningOutcomeGroup#learning_outcome_tags with LearningOutcomeGroup#child_outcome_links (and only use for outcome links; not tags for child groups) * split ContentTag#create_outcome_result into Submission#create_outcome_result, QuizSubmission#create_outcome_result, and RubricAssessment#create_outcome_result. fix some bugs along the way * refactor ContentTag.outcome_tags_for_banks and some code from QuizSubmission#(track_outcomes|update_outcomes_for_assessment_questions) into QuizSubmission#questions_and_alignments * refactor RubricAssociation#update_outcome_relations and Rubric#update_alignments into LearningOutcome.update_alignments * don't use ContentTag#rubric_association with outcome alignments; use the tag's content's rubric_association in its place (they should have been equal anyways) * refactor LearningOutcome.available_in_context and @context.root_outcome_group.sorted_all_outcomes (only time sorted_all_outcomes is used) into LearningOutcomeContext#available_outcomes and LearningOutcomeContext#available_outcome * overhaul LearningOutcomeGroup#sorted_content and rename to LearningOutcomeGroup#sorted_children. it not returns ContentTags (outcome links) and LearningOutcomeGroups, vs. LearningOutcomes and LearningOutcomeGroups; fix usages appropriately * fix UI for arranging/deleting outcome links and groups within a group to refer to the outcome link rather than the outcome Change-Id: I85d99f2634f7206332cb1f5d5ea575b428988d4b Reviewed-on: https://gerrit.instructure.com/12590 Reviewed-by: Jacob Fugal <jacob@instructure.com> Tested-by: Jacob Fugal <jacob@instructure.com>
2012-07-13 01:16:13 +08:00
alignments.each do |alignment|
if alignment.learning_outcome_id == rating[:learning_outcome_id]
create_outcome_result(alignment)
end
2011-02-01 09:57:29 +08:00
end
end
end
end
learning outcomes refactor This list is *NOT* complete, some items may have snuck in that I forgot to note, and/or some of the noted items may not be completely functional yet. Specs need to be written around a lot of this, other specs will no doubt need to be fixed. Some things, particularly around LearningOutcomeGroups will need data migrations that aren't there yet. * remove LearningOutcome.non_rubric_outcomes? and replace with false where invoked * remove LearningOutcome.enabled? and replace with true where invoked * remove never-taken branches * remove the shared/aligned_outcomes partial and it's supporting javascript, since it's now empty * remove js handler for add_outcome_alignment_link and supporting method since it only occurred in never-taken branches * mix LearningOutcomeContext into Course and Account * replace LearningOutcomeGroup.default_for(context) with LearningOutcomeContext#root_outcome_group * rename LearningOutcome#content_tags to LearningOutcome#alignments * rename LearningOutcomeGroup#content_tags to LearningOutcomeGroup#child_links, and properly restrict * remove ContentTag[Alignment]#rubric_association_id, add ContentTag[Alignment]#has_rubric_association? that looks at the presence of the content's rubric_association_id * condition off the assignment having a rubric_association rather than filtering tags by has_rubric_association (which just looks back at the assignment). all or none of the assignment's alignments are forced to have the association (via the assignment). this was true in practice before, is now codified (and more efficient) * rename AssessmentQuestionBank#learning_outcome_tags to AssessmentQuestionBank#learning_outcome_alignments * rename Assignment#learning_outcome_tags to Assignment#learning_outcome_alignments * rename Rubric#learning_outcome_tags to Rubric#learning_outcome_alignments * move/rename (Course|Account)#learning_outcome_tags to LearningOutcomeContext#learning_outcome_links * move/rename Account#learning_outcomes (corrected) and Course#learning_outcomes to LearningOutcomeContext#linked_learning_outcomes * move/rename Account#created_learning_outcomes and Course#created_learning_outcomes to LearningOutcomeContext#created_learning_outcomes * clarify and correct usage of linked_learning_outcomes vs. created_learning_outcomes * move/rename (Account|Account)#learning_outcome_groups to LearningOutcomeContext#learning_outcome_groups * remove unused Account#associated_learning_outcomes * just remove one link to a learning outcome when deleting * merge Account#has_outcomes?, Course#has_outcomes? and Course#has_outcomes into LearningOutcomeContext#has_outcomes?, add a use in Context#active_record_types * kill LearningOutcomeGroup#root_learning_outcome_group (unused) * rename LearningOutcomeResult#content_tag to LearningOutcomeResult#alignment * kill unused (and broken) OutcomesController#add_outcome_group * kill unused OutcomesController#update_outcomes_for_asset * kill unused OutcomesController#outcomes_for_asset * remove unused (outside specs, correct specs) AssessmentQuestionBank#outcomes= * remove unused ContentTag#learning_outcome_content * replace ContentTag.learning_outcome_tags_for(asset) (only ever called with asset=an assignment) with call to Assignment#learning_outcome_alignments * remove unused ContentTag.not_rubric * remove (now) unused ContentTag.include_outcome * remove unused LearningOutcome#learning_outcome_group_associations * avoid explicit use of ContentTag in outcome-related specs * replace LearningOutcomeGroup#learning_outcome_tags with LearningOutcomeGroup#child_outcome_links (and only use for outcome links; not tags for child groups) * split ContentTag#create_outcome_result into Submission#create_outcome_result, QuizSubmission#create_outcome_result, and RubricAssessment#create_outcome_result. fix some bugs along the way * refactor ContentTag.outcome_tags_for_banks and some code from QuizSubmission#(track_outcomes|update_outcomes_for_assessment_questions) into QuizSubmission#questions_and_alignments * refactor RubricAssociation#update_outcome_relations and Rubric#update_alignments into LearningOutcome.update_alignments * don't use ContentTag#rubric_association with outcome alignments; use the tag's content's rubric_association in its place (they should have been equal anyways) * refactor LearningOutcome.available_in_context and @context.root_outcome_group.sorted_all_outcomes (only time sorted_all_outcomes is used) into LearningOutcomeContext#available_outcomes and LearningOutcomeContext#available_outcome * overhaul LearningOutcomeGroup#sorted_content and rename to LearningOutcomeGroup#sorted_children. it not returns ContentTags (outcome links) and LearningOutcomeGroups, vs. LearningOutcomes and LearningOutcomeGroups; fix usages appropriately * fix UI for arranging/deleting outcome links and groups within a group to refer to the outcome link rather than the outcome Change-Id: I85d99f2634f7206332cb1f5d5ea575b428988d4b Reviewed-on: https://gerrit.instructure.com/12590 Reviewed-by: Jacob Fugal <jacob@instructure.com> Tested-by: Jacob Fugal <jacob@instructure.com>
2012-07-13 01:16:13 +08:00
def create_outcome_result(alignment)
# find or create the user's unique LearningOutcomeResult for this alignment
# of the assessment's associated object.
result = alignment.learning_outcome_results.
for_association(rubric_association).
where(user_id: user.id).
first_or_initialize
learning outcomes refactor This list is *NOT* complete, some items may have snuck in that I forgot to note, and/or some of the noted items may not be completely functional yet. Specs need to be written around a lot of this, other specs will no doubt need to be fixed. Some things, particularly around LearningOutcomeGroups will need data migrations that aren't there yet. * remove LearningOutcome.non_rubric_outcomes? and replace with false where invoked * remove LearningOutcome.enabled? and replace with true where invoked * remove never-taken branches * remove the shared/aligned_outcomes partial and it's supporting javascript, since it's now empty * remove js handler for add_outcome_alignment_link and supporting method since it only occurred in never-taken branches * mix LearningOutcomeContext into Course and Account * replace LearningOutcomeGroup.default_for(context) with LearningOutcomeContext#root_outcome_group * rename LearningOutcome#content_tags to LearningOutcome#alignments * rename LearningOutcomeGroup#content_tags to LearningOutcomeGroup#child_links, and properly restrict * remove ContentTag[Alignment]#rubric_association_id, add ContentTag[Alignment]#has_rubric_association? that looks at the presence of the content's rubric_association_id * condition off the assignment having a rubric_association rather than filtering tags by has_rubric_association (which just looks back at the assignment). all or none of the assignment's alignments are forced to have the association (via the assignment). this was true in practice before, is now codified (and more efficient) * rename AssessmentQuestionBank#learning_outcome_tags to AssessmentQuestionBank#learning_outcome_alignments * rename Assignment#learning_outcome_tags to Assignment#learning_outcome_alignments * rename Rubric#learning_outcome_tags to Rubric#learning_outcome_alignments * move/rename (Course|Account)#learning_outcome_tags to LearningOutcomeContext#learning_outcome_links * move/rename Account#learning_outcomes (corrected) and Course#learning_outcomes to LearningOutcomeContext#linked_learning_outcomes * move/rename Account#created_learning_outcomes and Course#created_learning_outcomes to LearningOutcomeContext#created_learning_outcomes * clarify and correct usage of linked_learning_outcomes vs. created_learning_outcomes * move/rename (Account|Account)#learning_outcome_groups to LearningOutcomeContext#learning_outcome_groups * remove unused Account#associated_learning_outcomes * just remove one link to a learning outcome when deleting * merge Account#has_outcomes?, Course#has_outcomes? and Course#has_outcomes into LearningOutcomeContext#has_outcomes?, add a use in Context#active_record_types * kill LearningOutcomeGroup#root_learning_outcome_group (unused) * rename LearningOutcomeResult#content_tag to LearningOutcomeResult#alignment * kill unused (and broken) OutcomesController#add_outcome_group * kill unused OutcomesController#update_outcomes_for_asset * kill unused OutcomesController#outcomes_for_asset * remove unused (outside specs, correct specs) AssessmentQuestionBank#outcomes= * remove unused ContentTag#learning_outcome_content * replace ContentTag.learning_outcome_tags_for(asset) (only ever called with asset=an assignment) with call to Assignment#learning_outcome_alignments * remove unused ContentTag.not_rubric * remove (now) unused ContentTag.include_outcome * remove unused LearningOutcome#learning_outcome_group_associations * avoid explicit use of ContentTag in outcome-related specs * replace LearningOutcomeGroup#learning_outcome_tags with LearningOutcomeGroup#child_outcome_links (and only use for outcome links; not tags for child groups) * split ContentTag#create_outcome_result into Submission#create_outcome_result, QuizSubmission#create_outcome_result, and RubricAssessment#create_outcome_result. fix some bugs along the way * refactor ContentTag.outcome_tags_for_banks and some code from QuizSubmission#(track_outcomes|update_outcomes_for_assessment_questions) into QuizSubmission#questions_and_alignments * refactor RubricAssociation#update_outcome_relations and Rubric#update_alignments into LearningOutcome.update_alignments * don't use ContentTag#rubric_association with outcome alignments; use the tag's content's rubric_association in its place (they should have been equal anyways) * refactor LearningOutcome.available_in_context and @context.root_outcome_group.sorted_all_outcomes (only time sorted_all_outcomes is used) into LearningOutcomeContext#available_outcomes and LearningOutcomeContext#available_outcome * overhaul LearningOutcomeGroup#sorted_content and rename to LearningOutcomeGroup#sorted_children. it not returns ContentTags (outcome links) and LearningOutcomeGroups, vs. LearningOutcomes and LearningOutcomeGroups; fix usages appropriately * fix UI for arranging/deleting outcome links and groups within a group to refer to the outcome link rather than the outcome Change-Id: I85d99f2634f7206332cb1f5d5ea575b428988d4b Reviewed-on: https://gerrit.instructure.com/12590 Reviewed-by: Jacob Fugal <jacob@instructure.com> Tested-by: Jacob Fugal <jacob@instructure.com>
2012-07-13 01:16:13 +08:00
# force the context and artifact
result.artifact = self
result.context = alignment.context
# mastery
criterion = rubric_association.rubric.data.find{|c| c[:learning_outcome_id] == alignment.learning_outcome_id }
criterion_result = self.data.find{|c| c[:criterion_id] == criterion[:id] }
if criterion
result.possible = criterion[:points]
result.score = criterion_result && criterion_result[:points]
result.mastery = result.score && (criterion[:mastery_points] || result.possible) && result.score >= (criterion[:mastery_points] || result.possible)
else
result.possible = nil
result.score = nil
result.mastery = nil
end
# attempt
if self.artifact && self.artifact.is_a?(Submission)
result.attempt = self.artifact.attempt || 1
updated learning outcome to retain eval method and info for weighted methods fixes CNVS-16915 (all mentions of 'gradebook' refer to learning mastery gradebook) test plan: - go to gradebook - all existing mastery scores should still default to highest score to retain accuracy of existing calculations - in rails console, set 'calculation_method' to 'latest' for an outcome - all results for that outcome should now show student's latest score on gradebook - in rails console, set method to 'highest' - all results for that outcome should now show student's highest score on gradebook - in rails console, set method to 'n_mastery' and set 'calculation_int' to a number between two and 5 - all results for that outcome should now show avg of student's higest n# of scores (#n being the number set for the outcome's 'calculation_int') - in rails console, set method to 'decaying_average' and set 'calculation_int' to 75 - scores should now appear as they did first time gradebook was viewed on step #2 - in rails console, set 'calculation_int' to 65 - scores for that outcome should now reflect decaying average with 65% weight given to most recent score, and 35% weight for avg of all prior scores - have a student make a new submission to an old assignment and give it a score - the re-submission should now be most recent score for 'latest' and 'decaying_average' methods - amend a score for an old submission without a new submission from the student - the amended score should not become the most recent, but still be accurately reflected in the 25%/35% part of the 'decaying_average' method Change-Id: I330c47cb2288d99e589deca00ddb5a8ee8103a91 Reviewed-on: https://gerrit.instructure.com/44935 Reviewed-by: Simon Williams <simon@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> QA-Review: Sean Lewis <slewis@instructure.com> Product-Review: Benjamin Porter <bporter@instructure.com>
2014-11-26 06:56:01 +08:00
result.submitted_at = self.artifact.submitted_at
learning outcomes refactor This list is *NOT* complete, some items may have snuck in that I forgot to note, and/or some of the noted items may not be completely functional yet. Specs need to be written around a lot of this, other specs will no doubt need to be fixed. Some things, particularly around LearningOutcomeGroups will need data migrations that aren't there yet. * remove LearningOutcome.non_rubric_outcomes? and replace with false where invoked * remove LearningOutcome.enabled? and replace with true where invoked * remove never-taken branches * remove the shared/aligned_outcomes partial and it's supporting javascript, since it's now empty * remove js handler for add_outcome_alignment_link and supporting method since it only occurred in never-taken branches * mix LearningOutcomeContext into Course and Account * replace LearningOutcomeGroup.default_for(context) with LearningOutcomeContext#root_outcome_group * rename LearningOutcome#content_tags to LearningOutcome#alignments * rename LearningOutcomeGroup#content_tags to LearningOutcomeGroup#child_links, and properly restrict * remove ContentTag[Alignment]#rubric_association_id, add ContentTag[Alignment]#has_rubric_association? that looks at the presence of the content's rubric_association_id * condition off the assignment having a rubric_association rather than filtering tags by has_rubric_association (which just looks back at the assignment). all or none of the assignment's alignments are forced to have the association (via the assignment). this was true in practice before, is now codified (and more efficient) * rename AssessmentQuestionBank#learning_outcome_tags to AssessmentQuestionBank#learning_outcome_alignments * rename Assignment#learning_outcome_tags to Assignment#learning_outcome_alignments * rename Rubric#learning_outcome_tags to Rubric#learning_outcome_alignments * move/rename (Course|Account)#learning_outcome_tags to LearningOutcomeContext#learning_outcome_links * move/rename Account#learning_outcomes (corrected) and Course#learning_outcomes to LearningOutcomeContext#linked_learning_outcomes * move/rename Account#created_learning_outcomes and Course#created_learning_outcomes to LearningOutcomeContext#created_learning_outcomes * clarify and correct usage of linked_learning_outcomes vs. created_learning_outcomes * move/rename (Account|Account)#learning_outcome_groups to LearningOutcomeContext#learning_outcome_groups * remove unused Account#associated_learning_outcomes * just remove one link to a learning outcome when deleting * merge Account#has_outcomes?, Course#has_outcomes? and Course#has_outcomes into LearningOutcomeContext#has_outcomes?, add a use in Context#active_record_types * kill LearningOutcomeGroup#root_learning_outcome_group (unused) * rename LearningOutcomeResult#content_tag to LearningOutcomeResult#alignment * kill unused (and broken) OutcomesController#add_outcome_group * kill unused OutcomesController#update_outcomes_for_asset * kill unused OutcomesController#outcomes_for_asset * remove unused (outside specs, correct specs) AssessmentQuestionBank#outcomes= * remove unused ContentTag#learning_outcome_content * replace ContentTag.learning_outcome_tags_for(asset) (only ever called with asset=an assignment) with call to Assignment#learning_outcome_alignments * remove unused ContentTag.not_rubric * remove (now) unused ContentTag.include_outcome * remove unused LearningOutcome#learning_outcome_group_associations * avoid explicit use of ContentTag in outcome-related specs * replace LearningOutcomeGroup#learning_outcome_tags with LearningOutcomeGroup#child_outcome_links (and only use for outcome links; not tags for child groups) * split ContentTag#create_outcome_result into Submission#create_outcome_result, QuizSubmission#create_outcome_result, and RubricAssessment#create_outcome_result. fix some bugs along the way * refactor ContentTag.outcome_tags_for_banks and some code from QuizSubmission#(track_outcomes|update_outcomes_for_assessment_questions) into QuizSubmission#questions_and_alignments * refactor RubricAssociation#update_outcome_relations and Rubric#update_alignments into LearningOutcome.update_alignments * don't use ContentTag#rubric_association with outcome alignments; use the tag's content's rubric_association in its place (they should have been equal anyways) * refactor LearningOutcome.available_in_context and @context.root_outcome_group.sorted_all_outcomes (only time sorted_all_outcomes is used) into LearningOutcomeContext#available_outcomes and LearningOutcomeContext#available_outcome * overhaul LearningOutcomeGroup#sorted_content and rename to LearningOutcomeGroup#sorted_children. it not returns ContentTags (outcome links) and LearningOutcomeGroups, vs. LearningOutcomes and LearningOutcomeGroups; fix usages appropriately * fix UI for arranging/deleting outcome links and groups within a group to refer to the outcome link rather than the outcome Change-Id: I85d99f2634f7206332cb1f5d5ea575b428988d4b Reviewed-on: https://gerrit.instructure.com/12590 Reviewed-by: Jacob Fugal <jacob@instructure.com> Tested-by: Jacob Fugal <jacob@instructure.com>
2012-07-13 01:16:13 +08:00
else
result.attempt = self.version_number
end
# title
result.title = "#{user.name}, #{rubric_association.title}"
result.assessed_at = Time.now
result.save_to_version(result.attempt)
result
end
2011-02-01 09:57:29 +08:00
def update_artifact_parameters
if self.artifact_type == 'Submission' && self.artifact
self.artifact_attempt = self.artifact.attempt
end
end
def htmlify_rating_comments
if self.data_changed? && self.data.present?
self.data.each do |rating|
if rating.is_a?(Hash) && rating[:comments].present?
rating[:comments_html] = format_message(rating[:comments]).first
end
end
end
true
end
2011-02-01 09:57:29 +08:00
def update_assessment_requests
requests = self.assessment_requests
fix anonymous peer review checkbox on graded discussion form. fixes CNVS-19782 The checkbox used to determine whether or not an assignment's peer reviews should be considered anonymous, which is part of a backbone view, did not function properly if it was 'nested' (i.e., if the name on the field should be `assiginment[anonymous_peer_reviews]`, instead of just `anonymous_peer_reviews`. The `checkbox` helper is already setup to handle this; we just needed to pass the `nested` value to it, and to update how we determine whether or not the checkbox should appear checked, so as to avoid manually setting the checkbox's `name` attribute. Additionally, this patch fixes a bug in the `RubricAssessment#considered_anonymous?` method, which would blow up if the model did not have a related rubric_association. I've added a protection to two other methods that would have thrown exceptions in the absence of a rubric_assocation as well. Finally, I updated the logic in the SubmissionComment policy declaration, so that when trying to `:read_author`, a student can always see the name of a teacher, even if the comment is marked as anonymous. test plan: - as a teacher, create a graded discussion topic. When doing say, enable peer reviews, and enable anonymous peer reviews. - as a student, submit an entry for the graded discussion topic. - as a teacher, assign a peer review to a student for the submission above. - as the reviewer student, submit a review. - as the reviewed student, navigate to the submission details page (/courses/:course_id/assignments/:assignment_id/submissions/:user_id) and observe the comment list on the right hand side of the page. - observe that the name of the reviewer student is not present, and instead it says 'Anonymous User'. - as the teacher, navigate to the same submission page, and observe the comment list on the right hand side of the page. - observe that the name of the reviewer student IS present. - as the teacher, navigate to the same submission page, and observe the comment list on the right hand side of the page - as the teacher, leave a comment on the submitted assignment. - as the reviewed student, navigate to the submission details page, and observe the comment list on the right hand side of the page. - observe that the name of the reviewer teacher IS present. Change-Id: I572dd7fa319cd784e59f00057898fcea5349c899 Reviewed-on: https://gerrit.instructure.com/52099 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-04-14 07:10:02 +08:00
if self.rubric_association.present?
requests += self.rubric_association.assessment_requests.where({
assessor_id: self.assessor_id,
asset_id: self.artifact_id,
asset_type: self.artifact_type
})
end
2011-02-01 09:57:29 +08:00
requests.each { |a|
a.attributes = {:rubric_assessment => self, :assessor => self.assessor}
a.complete
}
end
protected :update_assessment_requests
gpa scale grading standard fixes CNVS-8931 makes a new grading standard type called "gpa scale" only allows for grades on the GPA scale modifies GB2 dom elements if gpa scaled modifies rubric_assessment response to properly change grade adds dialog when selecting gpa scale grading type refactors grading_standard.rb to use instance methods (not class) added related tests test plan: - As a Teacher, create an assignment with GPA Scaled grading type - Enter a grading scheme like the one in grading_standard.rb/default_gpa_scheme - Go to GB2 and grade this assignment - grades not in the schema should be "-" - letters that aren't in the scheme should be a "-" - if "3.0" is in the grading standard an input of 3 should switch to 3.0 automatically - letters in the scheme should work upper or lower case - setting default grade should work with the same rules - dom elements of this assignment should have a special class - Other assignments should work as usual in GB2 - Go to Assignment Edit Page - when selecting Display Grade as "GPA Scale" a ? icon should pop up - clicking this icon should open a modal with sane text - Go to GB1 - Grading an assignment should work like GB2 - GB1 should work as expected for non GPA Scale Assignments - Go to the SpeedGrader - grading assignments that are GPA Scaled should work similarly to GB2 - SpeedGrader should work as expected for non GPA Scale Assignments - Enable Rubric based grading on an assignment - once the rubric is filled out in SpeedGrader, the correctly rounded GPA should be inserted on save - once the rubric is filled out in Submission Edit page, the correctly rounded GPA should be inserted on save - rubrics should work as expected for non GPA Scale Assignments - Other areas in which GradingStandards are used should work as expected Change-Id: Ide1ea5ca13a70116ae3535b2c8e105ece79a34c8 Reviewed-on: https://gerrit.instructure.com/29742 Reviewed-by: Simon Williams <simon@instructure.com> QA-Review: Amber Taniuchi <amber@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com> Product-Review: Mike Nomitch <mnomitch@instructure.com>
2014-02-05 01:57:32 +08:00
2011-02-01 09:57:29 +08:00
def attempt
self.artifact_type == 'Submission' ? self.artifact.attempt : nil
end
gpa scale grading standard fixes CNVS-8931 makes a new grading standard type called "gpa scale" only allows for grades on the GPA scale modifies GB2 dom elements if gpa scaled modifies rubric_assessment response to properly change grade adds dialog when selecting gpa scale grading type refactors grading_standard.rb to use instance methods (not class) added related tests test plan: - As a Teacher, create an assignment with GPA Scaled grading type - Enter a grading scheme like the one in grading_standard.rb/default_gpa_scheme - Go to GB2 and grade this assignment - grades not in the schema should be "-" - letters that aren't in the scheme should be a "-" - if "3.0" is in the grading standard an input of 3 should switch to 3.0 automatically - letters in the scheme should work upper or lower case - setting default grade should work with the same rules - dom elements of this assignment should have a special class - Other assignments should work as usual in GB2 - Go to Assignment Edit Page - when selecting Display Grade as "GPA Scale" a ? icon should pop up - clicking this icon should open a modal with sane text - Go to GB1 - Grading an assignment should work like GB2 - GB1 should work as expected for non GPA Scale Assignments - Go to the SpeedGrader - grading assignments that are GPA Scaled should work similarly to GB2 - SpeedGrader should work as expected for non GPA Scale Assignments - Enable Rubric based grading on an assignment - once the rubric is filled out in SpeedGrader, the correctly rounded GPA should be inserted on save - once the rubric is filled out in Submission Edit page, the correctly rounded GPA should be inserted on save - rubrics should work as expected for non GPA Scale Assignments - Other areas in which GradingStandards are used should work as expected Change-Id: Ide1ea5ca13a70116ae3535b2c8e105ece79a34c8 Reviewed-on: https://gerrit.instructure.com/29742 Reviewed-by: Simon Williams <simon@instructure.com> QA-Review: Amber Taniuchi <amber@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com> Product-Review: Mike Nomitch <mnomitch@instructure.com>
2014-02-05 01:57:32 +08:00
2011-02-01 09:57:29 +08:00
def update_artifact
if self.artifact_type == 'Submission' && self.artifact
Submission.where(:id => self.artifact).update_all(:has_rubric_assessment => true)
2011-02-01 09:57:29 +08:00
if self.rubric_association && self.rubric_association.use_for_grading && self.artifact.score != self.score
if self.rubric_association.association_object.grants_right?(self.assessor, nil, :grade)
# TODO: this should go through assignment.grade_student to
2011-02-01 09:57:29 +08:00
# handle group assignments.
self.artifact.workflow_state = 'graded'
self.artifact.update_attributes(:score => self.score, :graded_at => Time.now, :grade_matches_current_submission => true, :grader => self.assessor)
end
end
end
end
protected :update_artifact
2011-02-01 09:57:29 +08:00
set_policy do
given {|user| user && self.assessor_id == user.id }
can :create and can :read and can :update
given {|user| user && self.user_id == user.id }
can :read
given {|user, session| self.rubric_association && self.rubric_association.grants_right?(user, session, :manage) }
can :create and can :read and can :delete
2011-02-01 09:57:29 +08:00
given {|user, session| self.rubric_association && self.rubric_association.grants_right?(user, session, :view_rubric_assessments) }
can :read
given {|user, session|
self.rubric_association &&
self.rubric_association.grants_right?(user, session, :manage) &&
(self.rubric_association.association_object.context.grants_right?(self.assessor, :manage_rubrics) rescue false)
2011-02-01 09:57:29 +08:00
}
can :update
allow anonymous peer reviews; respect anonymity for reviewers Anonymous peer reviews will arrive in a couple of patches, but this is the first, and 1) allows an assignment to require anonymous peer reviews, and 2) respects anonymity from the perspective of the student whose work has been reviewed. A couple tangential changes: - update styles / html of _submission_sidebar on assignments page. - Update `submission_comment_model` factory to use `@submission` instance var if present. - Update `Submission#add_comment` to allow setting of recipient. fixes CNVS-5531 test plan: - As a teacher of a course with at least two students, create or edit an assignment. - Associate a rubric with the assignment. - Click the `Require Peer Reviews` check box, and observe the checkbox under the headline, "Anonymity." Click the checkbox labeled: "Peer Reviews Appear Anonymously." - As a student, we will call the reviewed, complete the assignment. - As the teacher, go to the assignment peer reviews page locate a user different than the one that completed the assignment above, we will call the reviewer, and assign them a peer review of the reviewed's assignment. - As the reviewer, log in and complete the peer review by leaving a coment, and by showing the rubric and adding number of points. - Observe that you are able to see your own name below the comment you have left. - Observe that, when you view the rubric, you can see your own name in the 'Show Assessment By' dropdown. - As the teacher, observe that you are able to see the reviewer's name underneath the comment they have left, and when you view the rubric, you can see the reviewer's name in the 'Show Assignment By' dropdown. - As the reviewed, observe that you are unable to see the review's name underneath the comment they have left, or in the 'Show Assignment By' drowndown when viewing the rubric. Change-Id: I1cadc7ac65a32188095949dfd758d4cd0883ac3e Reviewed-on: https://gerrit.instructure.com/47841 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> Reviewed-by: Matt Berns <mberns@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-01-28 01:10:08 +08:00
given {|user, session|
self.can_read_assessor_name?(user, session)
}
can :read_assessor
2011-02-01 09:57:29 +08:00
end
scope :of_type, lambda { |type| where(:assessment_type => type.to_s) }
2011-02-01 09:57:29 +08:00
def methods_for_serialization(*methods)
@serialization_methods = methods
end
def serialization_methods
@serialization_methods || []
end
2011-02-01 09:57:29 +08:00
def assessor_name
self.assessor.short_name rescue t('unknown_user', "Unknown User")
2011-02-01 09:57:29 +08:00
end
2011-02-01 09:57:29 +08:00
def assessment_url
self.artifact.url rescue nil
end
allow anonymous peer reviews; respect anonymity for reviewers Anonymous peer reviews will arrive in a couple of patches, but this is the first, and 1) allows an assignment to require anonymous peer reviews, and 2) respects anonymity from the perspective of the student whose work has been reviewed. A couple tangential changes: - update styles / html of _submission_sidebar on assignments page. - Update `submission_comment_model` factory to use `@submission` instance var if present. - Update `Submission#add_comment` to allow setting of recipient. fixes CNVS-5531 test plan: - As a teacher of a course with at least two students, create or edit an assignment. - Associate a rubric with the assignment. - Click the `Require Peer Reviews` check box, and observe the checkbox under the headline, "Anonymity." Click the checkbox labeled: "Peer Reviews Appear Anonymously." - As a student, we will call the reviewed, complete the assignment. - As the teacher, go to the assignment peer reviews page locate a user different than the one that completed the assignment above, we will call the reviewer, and assign them a peer review of the reviewed's assignment. - As the reviewer, log in and complete the peer review by leaving a coment, and by showing the rubric and adding number of points. - Observe that you are able to see your own name below the comment you have left. - Observe that, when you view the rubric, you can see your own name in the 'Show Assessment By' dropdown. - As the teacher, observe that you are able to see the reviewer's name underneath the comment they have left, and when you view the rubric, you can see the reviewer's name in the 'Show Assignment By' dropdown. - As the reviewed, observe that you are unable to see the review's name underneath the comment they have left, or in the 'Show Assignment By' drowndown when viewing the rubric. Change-Id: I1cadc7ac65a32188095949dfd758d4cd0883ac3e Reviewed-on: https://gerrit.instructure.com/47841 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> Reviewed-by: Matt Berns <mberns@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-01-28 01:10:08 +08:00
def can_read_assessor_name?(user, session)
self.assessment_type == 'grading' ||
allow anonymous peer reviews; respect anonymity for reviewers Anonymous peer reviews will arrive in a couple of patches, but this is the first, and 1) allows an assignment to require anonymous peer reviews, and 2) respects anonymity from the perspective of the student whose work has been reviewed. A couple tangential changes: - update styles / html of _submission_sidebar on assignments page. - Update `submission_comment_model` factory to use `@submission` instance var if present. - Update `Submission#add_comment` to allow setting of recipient. fixes CNVS-5531 test plan: - As a teacher of a course with at least two students, create or edit an assignment. - Associate a rubric with the assignment. - Click the `Require Peer Reviews` check box, and observe the checkbox under the headline, "Anonymity." Click the checkbox labeled: "Peer Reviews Appear Anonymously." - As a student, we will call the reviewed, complete the assignment. - As the teacher, go to the assignment peer reviews page locate a user different than the one that completed the assignment above, we will call the reviewer, and assign them a peer review of the reviewed's assignment. - As the reviewer, log in and complete the peer review by leaving a coment, and by showing the rubric and adding number of points. - Observe that you are able to see your own name below the comment you have left. - Observe that, when you view the rubric, you can see your own name in the 'Show Assessment By' dropdown. - As the teacher, observe that you are able to see the reviewer's name underneath the comment they have left, and when you view the rubric, you can see the reviewer's name in the 'Show Assignment By' dropdown. - As the reviewed, observe that you are unable to see the review's name underneath the comment they have left, or in the 'Show Assignment By' drowndown when viewing the rubric. Change-Id: I1cadc7ac65a32188095949dfd758d4cd0883ac3e Reviewed-on: https://gerrit.instructure.com/47841 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> Reviewed-by: Matt Berns <mberns@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-01-28 01:10:08 +08:00
!self.considered_anonymous? ||
self.assessor_id == user.id ||
self.rubric_association.association_object.context.grants_right?(
user, session, :view_all_grades
)
end
def considered_anonymous?
fix anonymous peer review checkbox on graded discussion form. fixes CNVS-19782 The checkbox used to determine whether or not an assignment's peer reviews should be considered anonymous, which is part of a backbone view, did not function properly if it was 'nested' (i.e., if the name on the field should be `assiginment[anonymous_peer_reviews]`, instead of just `anonymous_peer_reviews`. The `checkbox` helper is already setup to handle this; we just needed to pass the `nested` value to it, and to update how we determine whether or not the checkbox should appear checked, so as to avoid manually setting the checkbox's `name` attribute. Additionally, this patch fixes a bug in the `RubricAssessment#considered_anonymous?` method, which would blow up if the model did not have a related rubric_association. I've added a protection to two other methods that would have thrown exceptions in the absence of a rubric_assocation as well. Finally, I updated the logic in the SubmissionComment policy declaration, so that when trying to `:read_author`, a student can always see the name of a teacher, even if the comment is marked as anonymous. test plan: - as a teacher, create a graded discussion topic. When doing say, enable peer reviews, and enable anonymous peer reviews. - as a student, submit an entry for the graded discussion topic. - as a teacher, assign a peer review to a student for the submission above. - as the reviewer student, submit a review. - as the reviewed student, navigate to the submission details page (/courses/:course_id/assignments/:assignment_id/submissions/:user_id) and observe the comment list on the right hand side of the page. - observe that the name of the reviewer student is not present, and instead it says 'Anonymous User'. - as the teacher, navigate to the same submission page, and observe the comment list on the right hand side of the page. - observe that the name of the reviewer student IS present. - as the teacher, navigate to the same submission page, and observe the comment list on the right hand side of the page - as the teacher, leave a comment on the submitted assignment. - as the reviewed student, navigate to the submission details page, and observe the comment list on the right hand side of the page. - observe that the name of the reviewer teacher IS present. Change-Id: I572dd7fa319cd784e59f00057898fcea5349c899 Reviewed-on: https://gerrit.instructure.com/52099 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-04-14 07:10:02 +08:00
return false unless self.rubric_association.present?
allow anonymous peer reviews; respect anonymity for reviewers Anonymous peer reviews will arrive in a couple of patches, but this is the first, and 1) allows an assignment to require anonymous peer reviews, and 2) respects anonymity from the perspective of the student whose work has been reviewed. A couple tangential changes: - update styles / html of _submission_sidebar on assignments page. - Update `submission_comment_model` factory to use `@submission` instance var if present. - Update `Submission#add_comment` to allow setting of recipient. fixes CNVS-5531 test plan: - As a teacher of a course with at least two students, create or edit an assignment. - Associate a rubric with the assignment. - Click the `Require Peer Reviews` check box, and observe the checkbox under the headline, "Anonymity." Click the checkbox labeled: "Peer Reviews Appear Anonymously." - As a student, we will call the reviewed, complete the assignment. - As the teacher, go to the assignment peer reviews page locate a user different than the one that completed the assignment above, we will call the reviewer, and assign them a peer review of the reviewed's assignment. - As the reviewer, log in and complete the peer review by leaving a coment, and by showing the rubric and adding number of points. - Observe that you are able to see your own name below the comment you have left. - Observe that, when you view the rubric, you can see your own name in the 'Show Assessment By' dropdown. - As the teacher, observe that you are able to see the reviewer's name underneath the comment they have left, and when you view the rubric, you can see the reviewer's name in the 'Show Assignment By' dropdown. - As the reviewed, observe that you are unable to see the review's name underneath the comment they have left, or in the 'Show Assignment By' drowndown when viewing the rubric. Change-Id: I1cadc7ac65a32188095949dfd758d4cd0883ac3e Reviewed-on: https://gerrit.instructure.com/47841 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> Reviewed-by: Matt Berns <mberns@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
2015-01-28 01:10:08 +08:00
self.rubric_association.association_type == 'Assignment' &&
self.rubric_association.association_object.anonymous_peer_reviews?
end
2011-02-01 09:57:29 +08:00
def ratings
self.data
end
2011-02-01 09:57:29 +08:00
def related_group_submissions_and_assessments
if self.rubric_association && self.rubric_association.association_object.is_a?(Assignment) && !self.rubric_association.association_object.grade_group_students_individually
students = self.rubric_association.association_object.group_students(self.user).last
2011-02-01 09:57:29 +08:00
submissions = students.map do |student|
submission = self.rubric_association.association_object.find_asset_for_assessment(self.rubric_association, student.id).first
{:submission => submission, :rubric_assessments => submission.rubric_assessments.map{|ra| ra.as_json(:methods => :assessor_name)}}
2011-02-01 09:57:29 +08:00
end
else
[]
end
end
2011-02-01 09:57:29 +08:00
end