Class: Assignment
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Gamified
#award_experience_points!, #net_experience
#build_message, #has_messages?, #pending_messages?, #receive_answer!, #send_question!
#affable_expectation_results, #affable_test_results, #affable_tips, #expectation_results_visible?, #failed_expectation_results, #feedback_html, #first_test_result, #first_test_result_html, #humanized_expectation_results, #iconize, #queries_with_results, #result_html, #results_body_hidden?, #sanitized_affable_test_results, #single_visible_test_result?, #single_visual_result?, #single_visual_result_html, #test_result_html, #visible_expectation_results
Methods inherited from Progress
#_copy_to!, #delete_duplicates_in!, #dirty_parent_by_submission!, #guide_indicator?, #has_duplicates_in?, #parent, #transfer_to!
aggregate_of, all_except, defaults, #delete, #destroy!, numbered, organic_on, resource_fields, #save, #save_and_notify!, #save_and_notify_changes!, serialize_symbolized_hash_array, teaser_on, #update_and_notify!, update_or_create!, whitelist_attributes
Class Method Details
.build_for(user, exercise, organization) ⇒ Object
266
267
268
|
# File 'app/models/assignment.rb', line 266
def self.build_for(user, exercise, organization)
Assignment.new submitter: user, exercise: exercise, organization: organization
end
|
.evaluate_manually!(teacher_evaluation) ⇒ Object
126
127
128
|
# File 'app/models/assignment.rb', line 126
def self.evaluate_manually!(teacher_evaluation)
Assignment.find_by(submission_id: teacher_evaluation[:submission_id])&.evaluate_manually! teacher_evaluation
end
|
Instance Method Details
#attempts_left ⇒ Object
230
231
232
|
# File 'app/models/assignment.rb', line 230
def attempts_left
navigable_parent.attempts_left_for(self)
end
|
#attempts_left? ⇒ Boolean
Tells whether 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
238
239
240
|
# File 'app/models/assignment.rb', line 238
def attempts_left?
!limited? || attempts_left > 0
end
|
#completed_before_last_save? ⇒ Boolean
73
74
75
|
# File 'app/models/assignment.rb', line 73
def completed_before_last_save?
status_before_last_save.completed?
end
|
#completion_changed? ⇒ Boolean
69
70
71
|
# File 'app/models/assignment.rb', line 69
def completion_changed?
completed_before_last_save? != completed?
end
|
#content=(content) ⇒ Object
130
131
132
133
134
|
# File 'app/models/assignment.rb', line 130
def content=(content)
if exercise.solvable?
self.solution = exercise.single_choice? ? exercise.choice_index_for(content) : content
end
end
|
#current_content ⇒ Object
242
243
244
|
# File 'app/models/assignment.rb', line 242
def current_content
solution || default_content
end
|
#current_content_at(index) ⇒ Object
246
247
248
|
# File 'app/models/assignment.rb', line 246
def current_content_at(index)
exercise.sibling_at(index).assignment_for(submitter).current_content
end
|
#current_notification_contexts ⇒ Object
110
111
112
|
# File 'app/models/assignment.rb', line 110
def current_notification_contexts
[Organization.current, submitter.current_immersive_context_at(exercise)].uniq
end
|
#default_content ⇒ Object
250
251
252
|
# File 'app/models/assignment.rb', line 250
def default_content
@default_content ||= language.interpolate_references_for(self, exercise.default_content)
end
|
#errored!(message) ⇒ Object
178
179
180
|
# File 'app/models/assignment.rb', line 178
def errored!(message)
update! result: message, submission_status: :errored
end
|
#evaluate_manually!(teacher_evaluation) ⇒ Object
77
78
79
|
# File 'app/models/assignment.rb', line 77
def evaluate_manually!(teacher_evaluation)
update! status: teacher_evaluation[:status], manual_evaluation_comment: teacher_evaluation[:manual_evaluation]
end
|
#extension ⇒ Object
99
100
101
|
# File 'app/models/assignment.rb', line 99
def extension
exercise.language.extension
end
|
140
141
142
|
# File 'app/models/assignment.rb', line 140
def
exercise. && language.interpolate_references_for(self, exercise.)
end
|
144
145
146
|
# File 'app/models/assignment.rb', line 144
def
Mumukit::ContentType::Markdown.highlighted_code(language.name, )
end
|
#files ⇒ Object
254
255
256
|
# File 'app/models/assignment.rb', line 254
def files
exercise.files_for(current_content)
end
|
#increment_attempts! ⇒ Object
226
227
228
|
# File 'app/models/assignment.rb', line 226
def increment_attempts!
self.attempts_count += 1 if should_retry?
end
|
#manual_evaluation_pending! ⇒ Object
158
159
160
|
# File 'app/models/assignment.rb', line 158
def manual_evaluation_pending!
update! submission_status: :manual_evaluation_pending
end
|
#notify! ⇒ Object
103
104
105
106
107
108
|
# File 'app/models/assignment.rb', line 103
def notify!
unless Organization.silenced?
update_misplaced!(current_notification_contexts.size > 1)
Mumukit::Nuntius.notify! 'submissions', to_resource_h
end
end
|
#notify_to_accessible_organizations! ⇒ Object
114
115
116
117
|
# File 'app/models/assignment.rb', line 114
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
119
120
121
122
123
124
|
# File 'app/models/assignment.rb', line 119
def notify_to_student_granted_organizations!
submitter.student_granted_organizations.each do |organization|
organization.switch!
notify!
end
end
|
#passed! ⇒ Object
162
163
164
|
# File 'app/models/assignment.rb', line 162
def passed!
update! submission_status: :passed
end
|
#persist_submission!(submission) ⇒ Object
89
90
91
92
93
94
95
96
97
|
# File 'app/models/assignment.rb', line 89
def persist_submission!(submission)
transaction do
messages.destroy_all if submission_id.present?
update! submission_id: submission.id
update! submitted_at: DateTime.current
update_submissions_count!
update_last_submission!
end
end
|
#recontextualize!(new_organization = Organization.current) ⇒ Object
57
58
59
60
61
62
63
|
# File 'app/models/assignment.rb', line 57
def recontextualize!(new_organization = Organization.current)
if organization != new_organization
dirty_parent_by_submission! if organization.present? && exercise.used_in?(organization)
self.organization = new_organization
self.parent_id = nil
end
end
|
#run_tests!(params) ⇒ Object
187
188
189
|
# File 'app/models/assignment.rb', line 187
def run_tests!(params)
exercise.run_tests! params.merge(extra: , test: test, settings: settings)
end
|
#run_update! ⇒ Object
148
149
150
151
152
153
154
155
156
|
# File 'app/models/assignment.rb', line 148
def run_update!
running!
begin
update! yield
rescue => e
errored! e.message
raise e
end
end
|
#running! ⇒ Object
170
171
172
173
174
175
176
|
# File 'app/models/assignment.rb', line 170
def running!
update! submission_status: :running,
result: nil,
test_results: nil,
expectation_results: [],
manual_evaluation_comment: nil
end
|
#set_current_organization! ⇒ Object
TODO: Momentary as some assignments may not have an associated organization
53
54
55
|
# File 'app/models/assignment.rb', line 53
def set_current_organization!
self.organization = Organization.current
end
|
#set_default_top_submission_status ⇒ Object
65
66
67
|
# File 'app/models/assignment.rb', line 65
def set_default_top_submission_status
self.top_submission_status ||= 0
end
|
#skipped! ⇒ Object
166
167
168
|
# File 'app/models/assignment.rb', line 166
def skipped!
update! submission_status: :skipped
end
|
#test ⇒ Object
136
137
138
|
# File 'app/models/assignment.rb', line 136
def test
exercise.test && language.interpolate_references_for(self, exercise.test)
end
|
#tips ⇒ Object
222
223
224
|
# File 'app/models/assignment.rb', line 222
def tips
@tips ||= exercise.assist_with(self)
end
|
#to_resource_h ⇒ Object
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
# File 'app/models/assignment.rb', line 191
def to_resource_h
excluded_fields = i(created_at exercise_id id organization_id parent_id solution submission_id
submission_status submitted_at submitter_id top_submission_status updated_at misplaced)
as_json(except: excluded_fields,
include: {
guide: {
only: [:slug, :name],
include: {
lesson: {only: [:number]},
language: {only: [:name]}},
},
exercise: {only: [:name, :number]},
submitter: {only: [:email, :social_id, :uid], methods: [:name, :profile_picture]}}).
deep_merge(
'organization' => Organization.current.name,
'sid' => submission_id,
'created_at' => submitted_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
|
#update_misplaced!(value) ⇒ Object
262
263
264
|
# File 'app/models/assignment.rb', line 262
def update_misplaced!(value)
update! misplaced: value if value != misplaced?
end
|
#update_top_submission! ⇒ Object
258
259
260
|
# File 'app/models/assignment.rb', line 258
def update_top_submission!
self.top_submission_status = submission_status unless submission_status.improved_by?(top_submission_status)
end
|
#visible_status ⇒ Object
81
82
83
84
85
86
87
|
# File 'app/models/assignment.rb', line 81
def visible_status
if results_hidden? && !pending?
:manual_evaluation_pending.to_submission_status
else
super
end
end
|