From 58f5b01471a79d4e098f13ce2fd3765a140ffd1f Mon Sep 17 00:00:00 2001 From: rebuilt Date: Fri, 12 Aug 2022 02:56:25 -0700 Subject: [PATCH] Use less memory when loading race scores --- app/services/race_score_loader.rb | 9 +++---- spec/models/race_score_calulator_spec.rb | 31 ++++++++++++------------ spec/services/race_score_loader_spec.rb | 29 +++++++++++----------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/app/services/race_score_loader.rb b/app/services/race_score_loader.rb index a9bd89f0..f39f1479 100644 --- a/app/services/race_score_loader.rb +++ b/app/services/race_score_loader.rb @@ -1,27 +1,24 @@ class RaceScoreLoader def self.reset(schools: School.all, academic_years: AcademicYear.all, measures: Measure.all, races: Race.all) - RaceScore.where(school: schools, academic_year: academic_years, measure: measures, race: races).delete_all - scores = [] measures.each do |measure| schools.each do |school| academic_years.each do |academic_year| races.each do |race| - scores << process_score(measure:, school:, academic_year:, race:) + process_score(measure:, school:, academic_year:, race:) end end end end - RaceScore.import scores, batch_size: 1000 end private def self.process_score(measure:, school:, academic_year:, race:) score = RaceScoreCalculator.new(measure:, school:, academic_year:, race:).score - rs = RaceScore.new(measure:, school:, academic_year:, race:) + rs = RaceScore.find_or_create_by(measure:, school:, academic_year:, race:) rs.average = score.average rs.meets_student_threshold = score.meets_student_threshold? - rs + rs.save end private_class_method :process_score diff --git a/spec/models/race_score_calulator_spec.rb b/spec/models/race_score_calulator_spec.rb index def26dc7..91ad9a2d 100644 --- a/spec/models/race_score_calulator_spec.rb +++ b/spec/models/race_score_calulator_spec.rb @@ -5,11 +5,15 @@ describe RaceScoreCalculator do let(:school) { create(:school) } let(:academic_year) { create(:academic_year) } let(:race) { create(:race) } - let(:student) do - s = create(:student) - s.races << race - s.save - s + let(:students) do + [].tap do |arr| + 10.times do + s = create(:student) + s.races << race + s.save + arr << s + end + end end let(:survey_item_1) { measure.survey_items[0] } let(:survey_item_2) { measure.survey_items[1] } @@ -18,18 +22,15 @@ describe RaceScoreCalculator do create(:response_rate, school:, academic_year:, subcategory: measure.subcategory, meets_student_threshold: true) end - xcontext 'when survey item responses exist' do + context 'when survey item responses exist' do before :each do response_rate - create(:survey_item_response, school:, academic_year:, likert_score: 1, survey_item: survey_item_1, student:) - create_list(:survey_item_response, 8, school:, academic_year:, likert_score: 2, survey_item: survey_item_1, - student:) - create(:survey_item_response, school:, academic_year:, likert_score: 3, survey_item: survey_item_1, student:) - - create(:survey_item_response, school:, academic_year:, likert_score: 2, survey_item: survey_item_2, student:) - create_list(:survey_item_response, 8, school:, academic_year:, likert_score: 3, survey_item: survey_item_2, - student:) - create(:survey_item_response, school:, academic_year:, likert_score: 4, survey_item: survey_item_2, student:) + students.each do |student| + create(:survey_item_response, school:, academic_year:, likert_score: 2, survey_item: survey_item_1, student:) + end + students.each do |student| + create(:survey_item_response, school:, academic_year:, likert_score: 3, survey_item: survey_item_2, student:) + end end it 'returns a list of averages' do diff --git a/spec/services/race_score_loader_spec.rb b/spec/services/race_score_loader_spec.rb index aecf94fe..67f56dd4 100644 --- a/spec/services/race_score_loader_spec.rb +++ b/spec/services/race_score_loader_spec.rb @@ -5,11 +5,15 @@ describe RaceScoreLoader do let(:school) { create(:school) } let(:academic_year) { create(:academic_year) } let(:race) { create(:race) } - let(:student) do - s = create(:student) - s.races << race - s.save - s + let(:students) do + [].tap do |arr| + 10.times do + s = create(:student) + s.races << race + s.save + arr << s + end + end end let(:survey_item_1) { measure.survey_items[0] } let(:survey_item_2) { measure.survey_items[1] } @@ -22,18 +26,15 @@ describe RaceScoreLoader do context 'when survey item responses exist' do before :each do response_rate - create(:survey_item_response, school:, academic_year:, likert_score: 1, survey_item: survey_item_1, student:) - create_list(:survey_item_response, 8, school:, academic_year:, likert_score: 2, survey_item: survey_item_1, - student:) - create(:survey_item_response, school:, academic_year:, likert_score: 3, survey_item: survey_item_1, student:) + students.each do |student| + create(:survey_item_response, school:, academic_year:, likert_score: 2, survey_item: survey_item_1, student:) + end + students.each do |student| + create(:survey_item_response, school:, academic_year:, likert_score: 3, survey_item: survey_item_2, student:) + end - create(:survey_item_response, school:, academic_year:, likert_score: 2, survey_item: survey_item_2, student:) - create_list(:survey_item_response, 8, school:, academic_year:, likert_score: 3, survey_item: survey_item_2, - student:) - create(:survey_item_response, school:, academic_year:, likert_score: 4, survey_item: survey_item_2, student:) RaceScoreLoader.reset end - xit 'returns a list of averages' do expect(measure.student_survey_items.count).to eq 2 american_indian_score = RaceScore.find_by(measure:, school:, academic_year:, race:)