Class: Course::Assessment::Submission

Inherits:
ApplicationRecord show all
Includes:
NotificationConcern, TodoConcern, WorkflowEventConcern, Workflow
Defined in:
app/models/course/assessment/submission.rb

Defined Under Namespace

Modules: AnswersConcern, NotificationConcern, SubmissionsAutogradedHelper, SubmissionsControllerServiceConcern, SubmissionsHelper, TodoConcern, WorkflowEventConcern Classes: AutoGradingJob, AutoGradingService, Controller, Log, LogsController, PublishingJob, StatisticsDownloadJob, StatisticsDownloadService, SubmissionsController, UpdateService, ZipDownloadJob, ZipDownloadService

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TodoConcern

#todo

Methods included from WorkflowEventConcern

#finalise, #mark, #publish, #unmark, #unsubmit

Instance Attribute Details

#answersObject (readonly)

The answers associated with this submission. There can be more than one answer per submission, this is because every answer is saved over time. Use the latest scope of the answers if only the latest answer for each question is desired.


48
49
50
51
# File 'app/models/course/assessment/submission.rb', line 48

has_many :answers, class_name: Course::Assessment::Answer.name, dependent: :destroy,
                   inverse_of: :submission do
  include Course::Assessment::Submission::AnswersConcern
end

#graded_atTime (readonly)

Gets the time the submission was graded.


79
80
81
82
83
# File 'app/models/course/assessment/submission.rb', line 79

calculated :graded_at, (lambda do
  Course::Assessment::Answer.unscope(:order).
    where('course_assessment_answers.submission_id = course_assessment_submissions.id').
    select('max(course_assessment_answers.graded_at)')
end)

#gradersObject (readonly)

The graders associated with this submission.


67
# File 'app/models/course/assessment/submission.rb', line 67

has_many :graders, through: :answers, class_name: User.name

#log_countObject (readonly)

Returns the total number of access logs for the submission.


87
88
89
90
# File 'app/models/course/assessment/submission.rb', line 87

calculated :log_count, (lambda do
  Course::Assessment::Submission::Log.select("count('*')").
    where('course_assessment_submission_logs.submission_id = course_assessment_submissions.id')
end)

Class Method Details

.by_user(user) ⇒ Object

Finds all the submissions by the given user.


95
# File 'app/models/course/assessment/submission.rb', line 95

scope :by_user, ->(user) { where(creator: user) }

.by_users(user) ⇒ Object


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

scope :by_users, ->(user_ids) { where(creator_id: user_ids) }

.confirmedObject

Returns submissions which have been submitted (which may or may not be graded).


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

scope :confirmed, -> { where(workflow_state: [:submitted, :graded, :published]) }

.from_category(category) ⇒ Object

Finds all the submissions in the given category.


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

scope :from_category, (lambda do |category|
  where(assessment_id: category.assessments.select(:id))
end)

.ordered_by_dateObject

Orders the submissions by date of creation. This defaults to reverse chronological order (newest submission first).


121
# File 'app/models/course/assessment/submission.rb', line 121

scope :ordered_by_date, ->(direction = :desc) { order(created_at: direction) }

.ordered_by_submitted(date) ⇒ Object

Orders the submissions by date of submission (newest submission first).


125
# File 'app/models/course/assessment/submission.rb', line 125

scope :ordered_by_submitted_date, -> { order(submitted_at: :desc) }

Instance Method Details

#answer_historyObject

Loads the answer ids of the past answers of each question


184
185
186
187
188
189
190
191
# File 'app/models/course/assessment/submission.rb', line 184

def answer_history
  answers.unscope(:order).order(created_at: :desc).pluck(:question_id, :id, :current_answer).group_by(&:first).map do |pair|
    {
      question_id: pair[0],
      answer_ids: pair[1].reject(&:last).map(&:second).first(10)
    }
  end
end

#auto_grade!Course::Assessment::Submission::AutoGradingJob

Creates an Auto Grading job for this submission. This saves the submission if there are pending changes.


161
162
163
# File 'app/models/course/assessment/submission.rb', line 161

def auto_grade!
  AutoGradingJob.perform_later(self)
end

#current_answersObject

The answers with current_answer flag set to true.

If there are multiple current_answers for a particular question, return the first one. This guards against a race condition creating multiple current_answers for a given question in load_or_create_answers.


179
180
181
# File 'app/models/course/assessment/submission.rb', line 179

def current_answers
  answers.select(&:current_answer?).group_by(&:question_id).map { |pair| pair[1].first }
end

#current_points_awardedObject

Return the points awarded for the submission. If submission is 'graded', return the draft value, otherwise, the return the points awarded.


200
201
202
# File 'app/models/course/assessment/submission.rb', line 200

def current_points_awarded
  published? ? points_awarded : draft_points_awarded
end

#evaluated_or_graded_answers(question) ⇒ Object

Returns all graded answers of the question in current submission.


194
195
196
# File 'app/models/course/assessment/submission.rb', line 194

def evaluated_or_graded_answers(question)
  answers.select { |a| a.question_id == question.id && (a.evaluated? || a.graded?) }
end

#gradeObject

The total grade of the submission


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

def grade
  current_answers.map { |a| a.grade || 0 }.sum
end

#unsubmitting?Boolean


165
166
167
# File 'app/models/course/assessment/submission.rb', line 165

def unsubmitting?
  !!@unsubmitting
end