Class: Assignment

Inherits:
ApplicationRecord show all
Includes:
Contextualization, WithMessages
Defined in:
app/models/assignment.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from WithMessages

#build_message, #has_messages?, #pending_messages?, #receive_answer!, #send_question!

Methods included from Contextualization

#expectation_results_visible?, #failed_expectation_results, #feedback_html, #humanized_expectation_results, #queries_with_results, #result_html, #result_preview, #results_visible?, #single_visual_result?, #single_visual_result_html, #visible_expectation_results

Methods inherited from ApplicationRecord

aggregate_of, all_except, defaults, #delete, #destroy!, numbered, organic_on, resource_fields, #save, #save_and_notify!, #save_and_notify_changes!, serialize_symbolized_hash_array, #update_and_notify!, update_or_create!, whitelist_attributes

Class Method Details

.evaluate_manually!(teacher_evaluation) ⇒ Object



72
73
74
# File 'app/models/assignment.rb', line 72

def self.evaluate_manually!(teacher_evaluation)
  Assignment.find_by(submission_id: teacher_evaluation[:submission_id])&.evaluate_manually! teacher_evaluation
end

Instance Method Details

#attempts_leftObject



165
166
167
# File 'app/models/assignment.rb', line 165

def attempts_left
  navigable_parent.attempts_left_for(self)
end

#attempts_left?Boolean

Tells wether the submitter of this assignment can keep on sending submissions which is true for non limited or for assignments that have not reached their submissions limit

Returns:

  • (Boolean)


173
174
175
# File 'app/models/assignment.rb', line 173

def attempts_left?
  !limited? || attempts_left > 0
end

#content=(content) ⇒ Object



76
77
78
79
80
# File 'app/models/assignment.rb', line 76

def content=(content)
  if content.present?
    self.solution = exercise.single_choice? ? exercise.choice_index_for(content) : content
  end
end

#current_contentObject



177
178
179
# File 'app/models/assignment.rb', line 177

def current_content
  solution || default_content
end

#current_content_at(index) ⇒ Object



181
182
183
# File 'app/models/assignment.rb', line 181

def current_content_at(index)
  exercise.sibling_at(index).assignment_for(submitter).current_content
end

#default_contentObject



185
186
187
# File 'app/models/assignment.rb', line 185

def default_content
  @default_content ||= language.interpolate_references_for(self, exercise.default_content)
end

#errored!(message) ⇒ Object



116
117
118
# File 'app/models/assignment.rb', line 116

def errored!(message)
  update! result: message, submission_status: :errored
end

#evaluate_manually!(teacher_evaluation) ⇒ Object



39
40
41
# File 'app/models/assignment.rb', line 39

def evaluate_manually!(teacher_evaluation)
  update! status: teacher_evaluation[:status], manual_evaluation_comment: teacher_evaluation[:manual_evaluation]
end

#extensionObject



52
53
54
# File 'app/models/assignment.rb', line 52

def extension
  exercise.language.extension
end

#extraObject



86
87
88
# File 'app/models/assignment.rb', line 86

def extra
  exercise.extra && language.interpolate_references_for(self, exercise.extra)
end

#extra_previewObject



90
91
92
# File 'app/models/assignment.rb', line 90

def extra_preview
  Mumukit::ContentType::Markdown.highlighted_code(language.name, extra)
end

#filesObject



189
190
191
# File 'app/models/assignment.rb', line 189

def files
  exercise.files_for(current_content)
end

#increment_attempts!Object



161
162
163
# File 'app/models/assignment.rb', line 161

def increment_attempts!
  self.attempts_count += 1 if should_retry?
end

#notify!Object



56
57
58
# File 'app/models/assignment.rb', line 56

def notify!
  Mumukit::Nuntius.notify! 'submissions', to_resource_h unless Organization.silenced?
end

#notify_to_accessible_organizations!Object



60
61
62
63
# File 'app/models/assignment.rb', line 60

def notify_to_accessible_organizations!
  warn "Don't use notify_to_accessible_organizations!. Use notify_to_student_granted_organizations! instead"
  notify_to_student_granted_organizations!
end

#notify_to_student_granted_organizations!Object



65
66
67
68
69
70
# File 'app/models/assignment.rb', line 65

def notify_to_student_granted_organizations!
  submitter.student_granted_organizations.each do |organization|
    organization.switch!
    notify!
  end
end

#passed!Object



104
105
106
# File 'app/models/assignment.rb', line 104

def passed!
  update! submission_status: :passed
end

#persist_submission!(submission) ⇒ Object



43
44
45
46
47
48
49
50
# File 'app/models/assignment.rb', line 43

def persist_submission!(submission)
  transaction do
    messages.destroy_all if submission_id.present?
    update! submission_id: submission.id
    update_submissions_count!
    update_last_submission!
  end
end

#run_tests!(params) ⇒ Object



125
126
127
# File 'app/models/assignment.rb', line 125

def run_tests!(params)
  exercise.run_tests! params.merge(extra: extra, test: test, settings: settings)
end

#run_update!Object



94
95
96
97
98
99
100
101
102
# File 'app/models/assignment.rb', line 94

def run_update!
  running!
  begin
    update! yield
  rescue => e
    errored! e.message
    raise e
  end
end

#running!Object



108
109
110
111
112
113
114
# File 'app/models/assignment.rb', line 108

def running!
  update! submission_status: :running,
          result: nil,
          test_results: nil,
          expectation_results: [],
          manual_evaluation_comment: nil
end

#save!Object



193
194
195
196
# File 'app/models/assignment.rb', line 193

def save!(*)
  self.organization = Organization.current
  super
end

#testObject



82
83
84
# File 'app/models/assignment.rb', line 82

def test
  exercise.test && language.interpolate_references_for(self, exercise.test)
end

#tipsObject



157
158
159
# File 'app/models/assignment.rb', line 157

def tips
  @tips ||= exercise.assist_with(self)
end

#to_resource_hObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'app/models/assignment.rb', line 129

def to_resource_h
  as_json(except: [:exercise_id, :submission_id, :organization_id, :id, :submitter_id, :solution, :created_at, :updated_at, :submission_status],
            include: {
              guide: {
                only: [:slug, :name],
                include: {
                  lesson: {only: [:number]},
                  language: {only: [:name]}},
              },
              exercise: {only: [:name, :number]},
              submitter: {only: [:email, :image_url, :social_id, :uid], methods: [:name]}}).
    deep_merge(
      'organization' => Organization.current.name,
      'sid' => submission_id,
      'created_at' => updated_at,
      'content' => solution,
      'status' => submission_status,
      'exercise' => {
        'eid' => exercise.bibliotheca_id
      },
      'guide' => {'parent' => {
        'type' => navigable_parent.class.to_s,
        'name' => navigable_parent.name,
        'position' => navigable_parent.try(:number),
        'chapter' => guide.chapter.as_json(only: [:id], methods: [:name])
      }})
end