diff --git a/app/models/survey_item_response.rb b/app/models/survey_item_response.rb index 5e561160..21f05887 100644 --- a/app/models/survey_item_response.rb +++ b/app/models/survey_item_response.rb @@ -19,16 +19,22 @@ class SurveyItemResponse < ActiveRecord::Base scope :averages_for_grade, lambda { |survey_items, school, academic_year, grade| SurveyItemResponse.where(survey_item: survey_items, school:, - academic_year:, grade:).group(:survey_item).average(:likert_score) + academic_year:, grade:).group(:survey_item).having("count(*) >= 10").average(:likert_score) } scope :averages_for_gender, lambda { |survey_items, school, academic_year, gender| SurveyItemResponse.where(survey_item: survey_items, school:, - academic_year:, gender:).group(:survey_item).average(:likert_score) + academic_year:, gender:, grade: school.grades(academic_year:)).group(:survey_item).having("count(*) >= 10").average(:likert_score) } scope :averages_for_income, lambda { |survey_items, school, academic_year, income| SurveyItemResponse.where(survey_item: survey_items, school:, - academic_year:, income:).group(:survey_item).average(:likert_score) + academic_year:, income:, grade: school.grades(academic_year:)).group(:survey_item).having("count(*) >= 10").average(:likert_score) + } + + scope :averages_for_race, lambda { |school, academic_year, race| + SurveyItemResponse.joins("JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where( + school:, academic_year:, grade: school.grades(academic_year:) + ).where("student_races.race_id": race.id).group(:survey_item_id).having("count(*) >= 10").average(:likert_score) } end diff --git a/app/presenters/analyze/graph/column/gender_column/score_for_gender.rb b/app/presenters/analyze/graph/column/gender_column/score_for_gender.rb index 07dfb87c..2b5e22c4 100644 --- a/app/presenters/analyze/graph/column/gender_column/score_for_gender.rb +++ b/app/presenters/analyze/graph/column/gender_column/score_for_gender.rb @@ -5,11 +5,17 @@ module Analyze module ScoreForGender def score(year_index) academic_year = academic_years[year_index] + meets_student_threshold = sufficient_student_responses?(academic_year:) + return Score::NIL_SCORE unless meets_student_threshold + averages = SurveyItemResponse.averages_for_gender(measure.student_survey_items, school, academic_year, gender) average = bubble_up_averages(averages:).round(2) - scorify(average:, meets_student_threshold: sufficient_student_responses?(academic_year:)) + Score.new(average:, + meets_teacher_threshold: false, + meets_student_threshold:, + meets_admin_data_threshold: false) end def bubble_up_averages(averages:) @@ -20,16 +26,9 @@ module Analyze end.remove_blanks.average end - def scorify(average:, meets_student_threshold:) - return Score::NIL_SCORE unless meets_student_threshold - - Score.new(average:, - meets_teacher_threshold: false, - meets_student_threshold: true, - meets_admin_data_threshold: false) - end - def sufficient_student_responses?(academic_year:) + return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold? + yearly_counts = SurveyItemResponse.where(school:, academic_year:, gender:, survey_item: measure.student_survey_items).group(:gender).select(:response_id).distinct(:response_id).count yearly_counts.any? do |count| diff --git a/app/presenters/analyze/graph/column/grade/score_for_grade.rb b/app/presenters/analyze/graph/column/grade/score_for_grade.rb index 75e28b85..8b2e5d15 100644 --- a/app/presenters/analyze/graph/column/grade/score_for_grade.rb +++ b/app/presenters/analyze/graph/column/grade/score_for_grade.rb @@ -4,13 +4,17 @@ module Analyze module Grade module ScoreForGrade def score(year_index) + academic_year = academic_years[year_index] + meets_student_threshold = sufficient_student_responses?(academic_year:) + return Score::NIL_SCORE unless meets_student_threshold + averages = SurveyItemResponse.averages_for_grade(measure.student_survey_items, school, academic_years[year_index], grade) average = bubble_up_averages(averages:).round(2) Score.new(average:, meets_teacher_threshold: false, - meets_student_threshold: true, + meets_student_threshold:, meets_admin_data_threshold: false) end @@ -21,6 +25,16 @@ module Analyze end.remove_blanks.average end.remove_blanks.average end + + def sufficient_student_responses?(academic_year:) + return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold? + + yearly_counts = SurveyItemResponse.where(school:, academic_year:, + survey_item: measure.student_survey_items).group(:grade).select(:response_id).distinct(:response_id).count + yearly_counts.any? do |count| + count[1] >= 10 + end + end end end end diff --git a/app/presenters/analyze/graph/column/income_column/score_for_income.rb b/app/presenters/analyze/graph/column/income_column/score_for_income.rb index 3e1140c3..52a23244 100644 --- a/app/presenters/analyze/graph/column/income_column/score_for_income.rb +++ b/app/presenters/analyze/graph/column/income_column/score_for_income.rb @@ -5,11 +5,17 @@ module Analyze module ScoreForIncome def score(year_index) academic_year = academic_years[year_index] + meets_student_threshold = sufficient_student_responses?(academic_year:) + return Score::NIL_SCORE unless meets_student_threshold + averages = SurveyItemResponse.averages_for_income(measure.student_survey_items, school, academic_year, income) average = bubble_up_averages(averages:).round(2) - scorify(average:, meets_student_threshold: sufficient_student_responses?(academic_year:)) + Score.new(average:, + meets_teacher_threshold: false, + meets_student_threshold:, + meets_admin_data_threshold: false) end def bubble_up_averages(averages:) @@ -20,16 +26,9 @@ module Analyze end.remove_blanks.average end - def scorify(average:, meets_student_threshold:) - return Score::NIL_SCORE unless meets_student_threshold - - Score.new(average:, - meets_teacher_threshold: false, - meets_student_threshold: true, - meets_admin_data_threshold: false) - end - def sufficient_student_responses?(academic_year:) + return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold? + yearly_counts = SurveyItemResponse.where(school:, academic_year:, income:, survey_item: measure.student_survey_items).group(:income).select(:response_id).distinct(:response_id).count yearly_counts.any? do |count| diff --git a/app/presenters/analyze/graph/column/score_for_race.rb b/app/presenters/analyze/graph/column/score_for_race.rb index 207e198f..5fdc2e90 100644 --- a/app/presenters/analyze/graph/column/score_for_race.rb +++ b/app/presenters/analyze/graph/column/score_for_race.rb @@ -3,16 +3,37 @@ module Analyze module Column module ScoreForRace def score(year_index) - s = ::RaceScore.find_by(measure:, school:, academic_year: academic_years[year_index], race:) - average = s.average.round(2) unless s.nil? - average ||= 0 - meets_student_threshold = s.meets_student_threshold? unless s.nil? - meets_student_threshold ||= false + academic_year = academic_years[year_index] + meets_student_threshold = sufficient_student_responses?(academic_year:) + return Score::NIL_SCORE unless meets_student_threshold + + survey_items = measure.student_survey_items + + averages = SurveyItemResponse.averages_for_race(school, academic_year, race) + average = bubble_up_averages(averages:).round(2) + Score.new(average:, meets_teacher_threshold: false, meets_student_threshold:, meets_admin_data_threshold: false) end + + def bubble_up_averages(averages:) + measure.student_scales.map do |scale| + scale.survey_items.map do |survey_item| + averages[survey_item.id] + end.remove_blanks.average + end.remove_blanks.average + end + + def sufficient_student_responses?(academic_year:) + return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold? + + number_of_students_for_a_racial_group = SurveyItemResponse.joins("JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where( + school:, academic_year: + ).where("student_races.race_id": race.id).distinct.pluck(:student_id).count + number_of_students_for_a_racial_group >= 10 + end end end end diff --git a/app/services/survey_item_values.rb b/app/services/survey_item_values.rb index fb1ddd18..94399607 100644 --- a/app/services/survey_item_values.rb +++ b/app/services/survey_item_values.rb @@ -120,8 +120,6 @@ class SurveyItemValues return "Unknown" unless disaggregation_data.present? - byebug - disaggregation = disaggregation_data[[lasid, district.name, academic_year.range]] return "Unknown" unless disaggregation.present? @@ -248,4 +246,3 @@ class SurveyItemValues end end end -