diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_controller.rb index 54877304..ad8ebec6 100644 --- a/app/controllers/analyze_controller.rb +++ b/app/controllers/analyze_controller.rb @@ -74,7 +74,7 @@ class AnalyzeController < SqmApplicationController end def graphs - @graphs ||= [Analyze::Graph::StudentsAndTeachers.new, Analyze::Graph::StudentsByGroup.new] + @graphs ||= [Analyze::Graph::StudentsAndTeachers.new, Analyze::Graph::StudentsByGroup.new(races: selected_races)] end def background diff --git a/app/models/analyze/graph/students_by_group.rb b/app/models/analyze/graph/students_by_group.rb index d08bb1b3..d81b036d 100644 --- a/app/models/analyze/graph/students_by_group.rb +++ b/app/models/analyze/graph/students_by_group.rb @@ -1,6 +1,12 @@ module Analyze module Graph class StudentsByGroup + attr_reader :races + + def initialize(races:) + @races = races + end + def to_s 'Students by Group' end @@ -10,15 +16,30 @@ module Analyze end def columns - [Analyze::Graph::Column::AmericanIndian, - Analyze::Graph::Column::Asian, - Analyze::Graph::Column::Black, - Analyze::Graph::Column::Hispanic, - Analyze::Graph::Column::MiddleEastern, - Analyze::Graph::Column::Unknown, - Analyze::Graph::Column::White, - Analyze::Graph::Column::AllStudent] + [].tap do |array| + races.each do |race| + array << column_for_race_code(code: race.qualtrics_code) + end + array << Analyze::Graph::Column::AllStudent + end end + + private + + def column_for_race_code(code:) + CFR[code.to_s] + end + + CFR = { + '1' => Analyze::Graph::Column::AmericanIndian, + '2' => Analyze::Graph::Column::Asian, + '3' => Analyze::Graph::Column::Black, + '4' => Analyze::Graph::Column::Hispanic, + '5' => Analyze::Graph::Column::White, + '8' => Analyze::Graph::Column::MiddleEastern, + '99' => Analyze::Graph::Column::Unknown, + '100' => Analyze::Graph::Column::Multiracial + } end end end diff --git a/app/presenters/analyze/graph/column/multiracial.rb b/app/presenters/analyze/graph/column/multiracial.rb new file mode 100644 index 00000000..84ce0c81 --- /dev/null +++ b/app/presenters/analyze/graph/column/multiracial.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + class Multiracial < GroupedBarColumnPresenter + include Analyze::Graph::Column::RaceScore + def label + # TODO: offset labels so they don't overlap + 'Multiracial' + end + + def basis + 'student' + end + + def show_irrelevancy_message? + !measure.includes_student_survey_items? + end + + def show_insufficient_data_message? + # TODO: implement this logic. Resize messages so they are bound to their column + false + end + + def score(year_index) + # TODO: make sure the score calculation bubble up instead of just average + race_score(measure:, school:, academic_year: academic_years[year_index], race:) + end + + def race + Race.find_by_qualtrics_code 100 + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/race_score.rb b/app/presenters/analyze/graph/column/race_score.rb index 33ceb0da..188fc76b 100644 --- a/app/presenters/analyze/graph/column/race_score.rb +++ b/app/presenters/analyze/graph/column/race_score.rb @@ -4,10 +4,11 @@ module Analyze module RaceScore def race_score(measure:, school:, academic_year:, race:) survey_items = measure.student_survey_items + students = StudentRace.where(race:).pluck(:student_id) average = SurveyItemResponse.where(school:, academic_year:, survey_item: survey_items, - student: StudentRace.where(race:)) + student: students) .average(:likert_score) Score.new(average, true, true, true) end diff --git a/app/services/student_loader.rb b/app/services/student_loader.rb index ba29da93..180cd6b1 100644 --- a/app/services/student_loader.rb +++ b/app/services/student_loader.rb @@ -31,7 +31,7 @@ class StudentLoader lasid = row['LASID'] || row['lasid'] # return nil if student_exists?(response_id:) - student = create_student(response_id:, lasid:, races:) + student = find_or_create_student(response_id:, lasid:, races:) assign_student_to_responses(response_id:, student:) student @@ -51,7 +51,7 @@ class StudentLoader # SurveyItemResponse.import survey_responses, on_duplicate_key_update: { conflict_target: [:id], columns: [:student] } end - def self.create_student(response_id:, lasid:, races:) + def self.find_or_create_student(response_id:, lasid:, races:) student = Student.find_or_create_by(response_id:) student.races = [] races.each do |race| @@ -67,11 +67,17 @@ class StudentLoader code = 99 if [6, 7].include?(code) Race.find_by_qualtrics_code(code) end - remove_unknown_race_if_other_races_present(races: codes.to_set) + races = remove_unknown_race_if_other_races_present(races: codes.uniq) + add_multiracial_designation(races:) end def self.remove_unknown_race_if_other_races_present(races:) races.delete(Race.find_by_qualtrics_code(99)) if races.length > 1 races end + + def self.add_multiracial_designation(races:) + races << Race.find_by_qualtrics_code(100) if races.length > 1 + races + end end diff --git a/lib/tasks/data.rake b/lib/tasks/data.rake index fb4c429f..159f7559 100644 --- a/lib/tasks/data.rake +++ b/lib/tasks/data.rake @@ -67,7 +67,7 @@ namespace :data do end desc 'load students' task load_students: :environment do - Dir.glob(Rails.root.join('data', 'survey_responses', '*student*.csv')).each do |file| + Dir.glob(Rails.root.join('data', 'survey_responses', '2021-22*student*.csv')).each do |file| puts "=====================> Loading student data from csv at path: #{file}" StudentLoader.load_data filepath: file end diff --git a/spec/factories.rb b/spec/factories.rb index ed842f42..f8fe292e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -5,7 +5,7 @@ FactoryBot.define do end factory :race do - designation { "MyString" } + designation { "Race#{rand}" } qualtrics_code { 1 } end diff --git a/spec/presenters/analyze/graph/students_by_group_spec.rb b/spec/presenters/analyze/graph/students_by_group_spec.rb new file mode 100644 index 00000000..0eb82155 --- /dev/null +++ b/spec/presenters/analyze/graph/students_by_group_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' +include Analyze::Graph +include Analyze::Graph::Column +describe StudentsByGroup do + let(:american_indian) { create(:race, qualtrics_code: 1) } + let(:asian) { create(:race, qualtrics_code: 2) } + let(:black) { create(:race, qualtrics_code: 3) } + let(:hispanic) { create(:race, qualtrics_code: 4) } + let(:white) { create(:race, qualtrics_code: 5) } + let(:unknown) { create(:race, qualtrics_code: 99) } + let(:multiracial) { create(:race, qualtrics_code: 100) } + context 'when initialized with a list of races' do + it 'generates corresponding race columns' do + races = [american_indian] + expect(StudentsByGroup.new(races:).columns).to eq [AmericanIndian, AllStudent] + races = [american_indian, asian] + expect(StudentsByGroup.new(races:).columns).to eq [AmericanIndian, Asian, AllStudent] + races = [black, hispanic, multiracial] + expect(StudentsByGroup.new(races:).columns).to eq [Black, Hispanic, Multiracial, AllStudent] + end + end +end diff --git a/spec/services/student_loader_spec.rb b/spec/services/student_loader_spec.rb index de443b7c..2b297c72 100644 --- a/spec/services/student_loader_spec.rb +++ b/spec/services/student_loader_spec.rb @@ -9,6 +9,7 @@ describe StudentLoader do let(:white) { Race.find_by_qualtrics_code(5) } let(:middle_eastern) { Race.find_by_qualtrics_code(8) } let(:unknown) { Race.find_by_qualtrics_code(99) } + let(:multiracial) { Race.find_by_qualtrics_code(100) } before :each do Rails.application.load_seed @@ -21,21 +22,33 @@ describe StudentLoader do context 'as a standalone function' do it 'race codes of 6 or 7 get classified as an unknown race' do codes = [6] - expect(StudentLoader.process_races(codes:)).to eq Set[unknown] + expect(StudentLoader.process_races(codes:)).to eq [unknown] codes = [7] - expect(StudentLoader.process_races(codes:)).to eq Set[unknown] + expect(StudentLoader.process_races(codes:)).to eq [unknown] codes = [6, 7] - expect(StudentLoader.process_races(codes:)).to eq Set[unknown] + expect(StudentLoader.process_races(codes:)).to eq [unknown] codes = [1, 6, 7] - expect(StudentLoader.process_races(codes:)).to eq Set[american_indian] + expect(StudentLoader.process_races(codes:)).to eq [american_indian] end end end + describe '#add_multiracial_designation' do + it 'adds the multiracial race code to the list of races' do + races = [unknown] + expect(StudentLoader.add_multiracial_designation(races:)).to eq [unknown] + races = [american_indian, asian] + expect(StudentLoader.add_multiracial_designation(races:)).to eq [american_indian, asian, multiracial] + races = [white] + expect(StudentLoader.add_multiracial_designation(races:)).to eq [white] + end + end + + # This fails in CI because github does not know what the key derivation salt is. - # I'm not sure how to set the key derivation salt as an environment variable in CI + # I'm not sure how to securely set the key derivation salt as an environment variable in CI xdescribe 'self.load_data' do - context 'student survey responses' do + context 'load student data' do before :each do SurveyResponsesDataLoader.load_data filepath: path_to_student_responses StudentLoader.load_data filepath: path_to_student_responses @@ -59,13 +72,13 @@ end def assigns_races_to_students expect(Student.find_by_response_id('student_survey_response_1').races).to eq [american_indian] - expect(Student.find_by_response_id('student_survey_response_2').races).to eq [asian, black, latinx] + expect(Student.find_by_response_id('student_survey_response_2').races).to eq [asian, black, latinx, multiracial] expect(Student.find_by_response_id('student_survey_response_3').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_4').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_5').races).to eq [american_indian, asian, black, latinx, white, - middle_eastern] + middle_eastern, multiracial] expect(Student.find_by_response_id('student_survey_response_6').races).to eq [american_indian, asian, black, latinx, white, - middle_eastern] + middle_eastern, multiracial] expect(Student.find_by_response_id('student_survey_response_7').races).to eq [unknown] end diff --git a/spec/views/analyze/index.html.erb_spec.rb b/spec/views/analyze/index.html.erb_spec.rb index f26b71c4..47cac491 100644 --- a/spec/views/analyze/index.html.erb_spec.rb +++ b/spec/views/analyze/index.html.erb_spec.rb @@ -1,4 +1,3 @@ -# TODO: fix failing tests require 'rails_helper' include AnalyzeHelper include Analyze::Graph @@ -14,7 +13,7 @@ describe 'analyze/index' do end let(:graph) { StudentsAndTeachers.new } let(:graphs) do - [StudentsAndTeachers.new, StudentsByGroup.new] + [StudentsAndTeachers.new, StudentsByGroup.new(races:)] end let(:background) { BackgroundPresenter.new(num_of_columns: graph.columns.count) } let(:selected_races) { races }