canvas-lms/app/models/rubric_assessment.rb

148 lines
5.5 KiB
Ruby

#
# 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
# scoring using the rubric. Assessments are grouped together in one
# RubricAssociation, which may or may not have an association model.
class RubricAssessment < ActiveRecord::Base
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
has_many :assessment_requests, :dependent => :destroy
adheres_to_policy
serialize :data
simply_versioned
validates_presence_of :assessment_type
validates_length_of :comments, :maximum => maximum_text_length, :allow_nil => true, :allow_blank => true
before_save :update_artifact_parameters
after_save :update_assessment_requests, :update_artifact
after_save :track_outcomes
def track_outcomes
outcome_ids = (self.data || []).map{|r| r[:learning_outcome_id] }.compact.uniq
send_later(:update_outcomes_for_assessment, outcome_ids) unless outcome_ids.empty?
end
def update_outcomes_for_assessment(outcome_ids=[])
return if outcome_ids.empty?
tags = self.rubric_association.association.learning_outcome_tags.find_all_by_learning_outcome_id(outcome_ids)
(self.data || []).each do |rating|
if rating[:learning_outcome_id]
tags.select{|t| t.learning_outcome_id == rating[:learning_outcome_id]}.each do |tag|
tag.create_outcome_result(self.user, self.rubric_association.association, self)
end
end
end
end
def update_artifact_parameters
if self.artifact_type == 'Submission' && self.artifact
self.artifact_attempt = self.artifact.attempt
end
end
def update_assessment_requests
requests = self.assessment_requests
requests += self.rubric_association.assessment_requests.find_all_by_assessor_id_and_asset_id_and_asset_type(self.assessor_id, self.artifact_id, self.artifact_type)
requests.each { |a|
a.attributes = {:rubric_assessment => self, :assessor => self.assessor}
a.complete
}
end
protected :update_assessment_requests
def attempt
self.artifact_type == 'Submission' ? self.artifact.attempt : nil
end
def update_artifact
if self.artifact_type == 'Submission' && self.artifact
Submission.update_all({:has_rubric_assessment => true}, {:id => self.artifact.id})
if self.rubric_association && self.rubric_association.use_for_grading && self.artifact.score != self.score
if self.rubric_association.association.grants_right?(self.assessor, nil, :grade)
# TODO: this should go through assignment.grade_student to
# 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
set_policy do
given {|user, session| session && session[:rubric_assessment_ids] && session[:rubric_assessment_ids].include?(self.id) }
set { can :create and can :read and can :update }
given {|user, session| user && self.assessor_id == user.id }
set { can :create and can :read and can :update }
given {|user, session| user && self.user_id == user.id }
set { can :read }
given {|user, session| self.rubric_association && self.rubric_association.grants_rights?(user, session, :manage)[:manage] }
set { can :create and can :read and can :delete}
given {|user, session|
self.rubric_association &&
self.rubric_association.grants_rights?(user, session, :manage)[:manage] &&
(self.rubric_association.association.context.grants_right?(self.assessor, nil, :manage_grades) rescue false)
}
set { can :update }
end
named_scope :of_type, lambda {|type|
{:conditions => ['rubric_assessments.assessment_type = ?', type.to_s]}
}
def methods_for_serialization(*methods)
@serialization_methods = methods
end
def assessor_name
self.assessor.name rescue "Unknown User"
end
def assessment_url
self.artifact.url rescue nil
end
def ratings
self.data
end
def related_group_submissions_and_assessments
if self.rubric_association && self.rubric_association.association.is_a?(Assignment) && !self.rubric_association.association.grade_group_students_individually
students = self.rubric_association.association.group_students(self.user).last
submissions = students.map do |student|
submission = self.rubric_association.association.find_asset_for_assessment(self.rubric_association, student.id).first
{:submission => submission, :rubric_assessments => submission.rubric_assessments}
end
else
[]
end
end
end