Skip to content

Commit 55f75e8

Browse files
committed
move evaluate_for into the progression object
Change-Id: I94f6a66348827b7138ca0e5e1d45008b17f79894 Reviewed-on: https://gerrit.instructure.com/30981 Tested-by: Jenkins <jenkins@instructure.com> QA-Review: Matt Fairbourn <mfairbourn@instructure.com> Reviewed-by: Jeremy Stanley <jeremy@instructure.com> Product-Review: Jeremy Stanley <jeremy@instructure.com>
1 parent 82e46a9 commit 55f75e8

2 files changed

Lines changed: 121 additions & 107 deletions

File tree

app/models/context_module.rb

Lines changed: 15 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,10 @@ def active_prerequisites
412412
def clear_cached_lookups
413413
@cached_tags = nil
414414
end
415+
416+
def cached_tags
417+
@cached_tags ||= self.content_tags.active
418+
end
415419

416420
def re_evaluate_for(users, skip_confirm_valid_requirements=false)
417421
users = Array(users)
@@ -494,114 +498,18 @@ def content_tags_hash
494498
self.content_tags.each{|t| @tags_hash[t.id] = t }
495499
@tags_hash
496500
end
497-
498-
def evaluate_for(user, recursive_check=false, deep_check=false)
499-
progression = nil
500-
if user.is_a?(ContextModuleProgression)
501-
progression = user
502-
user = progression.user
503-
end
504-
return nil unless user
505-
progression ||= self.find_or_create_progression_with_multiple_lookups(user)
506-
return unless progression
507-
if self.unpublished?
508-
progression.workflow_state = 'locked'
509-
Shackles.activate(:master) do
510-
progression.save if progression.workflow_state_changed?
511-
end
512-
return progression
513-
end
514-
requirements_met_changed = false
515-
if User.module_progression_jobs_queued?(user.id)
516-
progression.workflow_state = 'locked'
517-
end
518-
if deep_check
519-
confirm_valid_requirements(true) rescue nil
520-
end
521-
@cached_tags ||= self.content_tags.active
522-
tags = @cached_tags
523-
if recursive_check || progression.new_record? || progression.updated_at < self.updated_at || User.module_progression_jobs_queued?(user.id)
524-
if self.completion_requirements.blank? && active_prerequisites.empty?
525-
progression.workflow_state = 'completed'
526-
Shackles.activate(:master) do
527-
progression.save
528-
end
529-
end
530-
progression.workflow_state = 'locked'
531-
if !self.to_be_unlocked
532-
progression.requirements_met ||= []
533-
if progression.locked?
534-
progression.workflow_state = 'unlocked' if self.prerequisites_satisfied?(user)
535-
end
536-
if progression.unlocked? || progression.started?
537-
orig_reqs = (progression.requirements_met || []).map{|r| "#{r[:id]}_#{r[:type]}" }.sort
538-
completes = (self.completion_requirements || []).map do |req|
539-
tag = tags.detect{|t| t.id == req[:id].to_i}
540-
if !tag
541-
res = true
542-
elsif ['min_score', 'max_score', 'must_submit'].include?(req[:type]) && !tag.scoreable?
543-
res = true
544-
else
545-
progression.evaluate_requirements_met if deep_check
546-
res = progression.requirements_met.any?{|r| r[:id] == req[:id] && r[:type] == req[:type] } #include?(req)
547-
if req[:type] == 'min_score'
548-
progression.requirements_met = progression.requirements_met.select{|r| r[:id] != req[:id] || r[:type] != req[:type]}
549-
if tag.content_type_quiz?
550-
submission = Quizzes::QuizSubmission.find_by_quiz_id_and_user_id(tag.content_id, user.id)
551-
score = submission.try(:kept_score)
552-
elsif tag.content_type == "DiscussionTopic"
553-
if tag.content
554-
submission = Submission.find_by_assignment_id_and_user_id(tag.content.assignment_id, user.id)
555-
score = submission.try(:score)
556-
else
557-
score = nil
558-
end
559-
else
560-
submission = Submission.find_by_assignment_id_and_user_id(tag.content_id, user.id)
561-
score = submission.try(:score)
562-
end
563-
if score && score >= req[:min_score].to_f
564-
progression.requirements_met << req
565-
res = true
566-
else
567-
res = false
568-
end
569-
end
570-
end
571-
res
572-
end
573-
new_reqs = (progression.requirements_met || []).map{|r| "#{r[:id]}_#{r[:type]}" }.sort
574-
requirements_met_changed = new_reqs != orig_reqs
575-
progression.workflow_state = 'started' if completes.any?
576-
progression.workflow_state = 'completed' if completes.all?
577-
end
578-
end
579-
end
580-
position = nil
581-
found_failure = false
582-
if self.require_sequential_progress
583-
tags.each do |tag|
584-
requirements_for_tag = (self.completion_requirements || []).select{|r| r[:id] == tag.id }.sort_by{|r| r[:id]}
585-
next if found_failure
586-
if requirements_for_tag.empty?
587-
position = tag.position
588-
else
589-
all_met = requirements_for_tag.all? do |req|
590-
(progression.requirements_met || []).any?{|r| r[:id] == req[:id] && r[:type] == req[:type] }
591-
end
592-
if all_met
593-
position = tag.position if tag.position && all_met
594-
else
595-
position = tag.position
596-
found_failure = true
597-
end
598-
end
599-
end
600-
end
601-
progression.current_position = position
602-
Shackles.activate(:master) do
603-
progression.save if progression.workflow_state_changed? || requirements_met_changed
501+
502+
def evaluate_for(user_or_progression, recursive_check=false, deep_check=false)
503+
if user_or_progression.is_a?(ContextModuleProgression)
504+
progression, user = [user_or_progression, user_or_progression.user]
505+
else
506+
progression, user = [self.find_or_create_progression_with_multiple_lookups(user_or_progression), user_or_progression] if user_or_progression
604507
end
508+
return nil unless progression && user
509+
510+
progression.context_module = self if progression.context_module_id == self.id
511+
progression.user = user if progression.user_id == user.id
512+
progression.evaluate(recursive_check, deep_check)
605513
progression
606514
end
607515

app/models/context_module_progression.rb

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,112 @@ def mark_as_dirty!
143143
nil
144144
end
145145

146+
def mark_as_complete
147+
self.workflow_state = 'completed'
148+
nil
149+
end
150+
151+
def mark_as_complete!
152+
mark_as_complete
153+
Shackles.activate(:master) do
154+
self.save if self.workflow_state_changed?
155+
end
156+
nil
157+
end
158+
159+
def evaluate(recursive_check=false, deep_check=false)
160+
# there is no valid progression state for unpublished modules
161+
return mark_as_dirty! if context_module.unpublished?
162+
163+
requirements_met_changed = false
164+
if User.module_progression_jobs_queued?(user.id)
165+
mark_as_dirty
166+
end
167+
if deep_check
168+
context_module.confirm_valid_requirements(true) rescue nil
169+
end
170+
tags = context_module.cached_tags
171+
if recursive_check || self.new_record? || self.updated_at < context_module.updated_at || User.module_progression_jobs_queued?(user.id)
172+
if context_module.completion_requirements.blank? && context_module.active_prerequisites.empty?
173+
mark_as_complete!
174+
end
175+
mark_as_dirty
176+
if !context_module.to_be_unlocked
177+
self.requirements_met ||= []
178+
if self.locked?
179+
self.workflow_state = 'unlocked' if context_module.prerequisites_satisfied?(user)
180+
end
181+
if self.unlocked? || self.started?
182+
orig_reqs = (self.requirements_met || []).map{|r| "#{r[:id]}_#{r[:type]}" }.sort
183+
completes = (context_module.completion_requirements || []).map do |req|
184+
tag = tags.detect{|t| t.id == req[:id].to_i}
185+
if !tag
186+
res = true
187+
elsif ['min_score', 'max_score', 'must_submit'].include?(req[:type]) && !tag.scoreable?
188+
res = true
189+
else
190+
self.evaluate_requirements_met if deep_check
191+
res = self.requirements_met.any?{|r| r[:id] == req[:id] && r[:type] == req[:type] } #include?(req)
192+
if req[:type] == 'min_score'
193+
self.requirements_met = self.requirements_met.select{|r| r[:id] != req[:id] || r[:type] != req[:type]}
194+
if tag.content_type_quiz?
195+
submission = Quizzes::QuizSubmission.find_by_quiz_id_and_user_id(tag.content_id, user.id)
196+
score = submission.try(:kept_score)
197+
elsif tag.content_type == "DiscussionTopic"
198+
if tag.content
199+
submission = Submission.find_by_assignment_id_and_user_id(tag.content.assignment_id, user.id)
200+
score = submission.try(:score)
201+
else
202+
score = nil
203+
end
204+
else
205+
submission = Submission.find_by_assignment_id_and_user_id(tag.content_id, user.id)
206+
score = submission.try(:score)
207+
end
208+
if score && score >= req[:min_score].to_f
209+
self.requirements_met << req
210+
res = true
211+
else
212+
res = false
213+
end
214+
end
215+
end
216+
res
217+
end
218+
new_reqs = (self.requirements_met || []).map{|r| "#{r[:id]}_#{r[:type]}" }.sort
219+
requirements_met_changed = new_reqs != orig_reqs
220+
self.workflow_state = 'started' if completes.any?
221+
self.workflow_state = 'completed' if completes.all?
222+
end
223+
end
224+
end
225+
position = nil
226+
found_failure = false
227+
if context_module.require_sequential_progress
228+
tags.each do |tag|
229+
requirements_for_tag = (context_module.completion_requirements || []).select{|r| r[:id] == tag.id }.sort_by{|r| r[:id]}
230+
next if found_failure
231+
if requirements_for_tag.empty?
232+
position = tag.position
233+
else
234+
all_met = requirements_for_tag.all? do |req|
235+
(self.requirements_met || []).any?{|r| r[:id] == req[:id] && r[:type] == req[:type] }
236+
end
237+
if all_met
238+
position = tag.position if tag.position && all_met
239+
else
240+
position = tag.position
241+
found_failure = true
242+
end
243+
end
244+
end
245+
end
246+
self.current_position = position
247+
Shackles.activate(:master) do
248+
self.save if self.workflow_state_changed? || requirements_met_changed
249+
end
250+
end
251+
146252
def trigger_completion_events
147253
if workflow_state_changed? && completed?
148254
context_module.completion_event_callbacks.each do |event|

0 commit comments

Comments
 (0)