Class: Course::Assessment

Inherits:
ApplicationRecord show all
Includes:
TodoConcern, ClosingReminderConcern, DuplicationStateTrackingConcern
Defined in:
app/models/course/assessment.rb

Overview

Represents an assessment in Coursemology, as well as the enclosing module for associated models.

An assessment is a collection of questions that can be asked.

Defined Under Namespace

Modules: AssessmentAbility, AssessmentsHelper, QuestionsConcern, SkillAbility, SubmissionQuestionAbility, SubmissionsHelper, TodoConcern Classes: AchievementPreloadService, Answer, AssessmentsController, AuthenticationService, CategoriesController, Category, ClosingReminderJob, ComponentController, Controller, ProgrammingEvaluationService, ProgrammingPackage, ProgrammingTestCaseReport, Question, QuestionsController, ReminderService, SessionAuthenticationService, SessionLogService, SessionsController, Skill, SkillBranch, SkillBranchesController, SkillsController, Submission, SubmissionQuestion, SubmissionsController, Tab

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DuplicationStateTrackingConcern

#clear_duplication_flag, #duplicating?, #set_duplication_flag

Methods included from TodoConcern

#can_user_start?

Instance Attribute Details

#maximum_gradeInteger (readonly)

Gets the maximum grade allowed by this assessment. This is the sum of all questions' maximum grade.

Returns:

  • (Integer)

57
58
59
60
61
62
63
64
# File 'app/models/course/assessment.rb', line 57

calculated :maximum_grade, (lambda do
  Course::Assessment::Question.
    select('coalesce(sum(caq.maximum_grade), 0)').
    from(
      "course_assessment_questions caq INNER JOIN course_question_assessments cqa ON \
      cqa.assessment_id = course_assessments.id AND cqa.question_id = caq.id"
    )
end)

Class Method Details

.ordered_by_date_and_titleObject

Orders the assessments by the starting date and title.


68
69
70
71
72
73
74
# File 'app/models/course/assessment.rb', line 68

scope :ordered_by_date_and_title, (lambda do
  select(<<~SQL).
  joins(:lesson_plan_item).
  merge(Course::LessonPlan::Item.ordered_by_date_and_title)
  course_assessments.*, course_lesson_plan_items.start_at, course_lesson_plan_items.title
  SQL
end)

.use_relative_model_naming?Boolean

Returns:

  • (Boolean)

99
100
101
# File 'app/models/course/assessment.rb', line 99

def self.use_relative_model_naming?
  true
end

Instance Method Details

#allow_mode_switching?Boolean

Whether the assessment allows mode switching. Allow mode switching if:

  • The assessment don't have any submissions.
  • Switching from autograded mode to manually graded mode.

Returns:

  • (Boolean)

128
129
130
# File 'app/models/course/assessment.rb', line 128

def allow_mode_switching?
  submissions.count == 0 || autograded?
end

#downloadable?Boolean

Returns:

  • (Boolean)

155
156
157
# File 'app/models/course/assessment.rb', line 155

def downloadable?
  questions.any?(&:downloadable?)
end

#include_in_consolidated_email?(event) ⇒ Boolean

Returns:

  • (Boolean)

169
170
171
172
# File 'app/models/course/assessment.rb', line 169

def include_in_consolidated_email?(event)
  Course::Settings::AssessmentsComponent.email_enabled?(tab.category,
                                                        "assessment_#{event}".to_sym)
end

#initialize_duplicate(duplicator, other) ⇒ Object


159
160
161
162
163
164
165
166
167
# File 'app/models/course/assessment.rb', line 159

def initialize_duplicate(duplicator, other)
  copy_attributes(other, duplicator)
  target_tab = initialize_duplicate_tab(duplicator, other)
  self.folder = duplicator.duplicate(other.folder)
  folder.parent = target_tab.category.folder
  self.question_assessments = duplicator.duplicate(other.question_assessments)
  initialize_duplicate_conditions(duplicator, other)
  set_duplication_flag
end

#permitted_for!(_course_user) ⇒ Object


133
134
# File 'app/models/course/assessment.rb', line 133

def permitted_for!(_course_user)
end

#precluded_for!(_course_user) ⇒ Object


137
138
# File 'app/models/course/assessment.rb', line 137

def precluded_for!(_course_user)
end

#satisfiable?Boolean

Returns:

  • (Boolean)

141
142
143
# File 'app/models/course/assessment.rb', line 141

def satisfiable?
  published?
end

#session_password_protected?Boolean

The password to prevent attempting submission from multiple sessions.

Returns:

  • (Boolean)

151
152
153
# File 'app/models/course/assessment.rb', line 151

def session_password_protected?
  session_password.present?
end

#to_partial_pathObject


103
104
105
# File 'app/models/course/assessment.rb', line 103

def to_partial_path
  'course/assessment/assessments/assessment'
end

#update_mode(params) ⇒ Object

Update assessment mode from params.

Parameters:

  • params (Hash)

    Params with autograded mode from user.


110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'app/models/course/assessment.rb', line 110

def update_mode(params)
  target_mode = params[:autograded]
  return if target_mode == autograded || !allow_mode_switching?

  if target_mode == true
    self.autograded = true
    self.session_password = nil
    self.delayed_grade_publication = false
  elsif target_mode == false # Ignore the case when the params is empty.
    self.autograded = false
    self.skippable = false
  end
end

#view_password_protected?Boolean

The password to prevent from viewing the assessment.

Returns:

  • (Boolean)

146
147
148
# File 'app/models/course/assessment.rb', line 146

def view_password_protected?
  view_password.present?
end

#with_submissions_by(creator) ⇒ Object

Includes the submissions by the provided user.

Parameters:

  • user (User)

    The user to preload submissions for.


79
80
81
82
83
84
85
86
87
# File 'app/models/course/assessment.rb', line 79

scope :with_submissions_by, (lambda do |user|
  submissions = Course::Assessment::Submission.by_user(user).
                where(assessment: distinct(false).pluck(:id)).ordered_by_date

  all.to_a.tap do |result|
    preloader = ActiveRecord::Associations::Preloader::ManualPreloader.new
    preloader.preload(result, :submissions, submissions)
  end
end)