You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sqm-dashboards/app/models/survey_item_response.rb

105 lines
5.3 KiB

class SurveyItemResponse < ActiveRecord::Base
TEACHER_RESPONSE_THRESHOLD = 17
STUDENT_RESPONSE_THRESHOLD = 196
belongs_to :academic_year
belongs_to :school
belongs_to :survey_item
def self.score_for_subcategory(subcategory:, school:, academic_year:)
measures = measures_with_sufficient_data(subcategory: subcategory, school: school, academic_year: academic_year)
return nil unless measures.size.positive?
measures.map do |measure|
responses_for_measure(measure: measure, school: school, academic_year: academic_year).average(:likert_score)
end.average
end
def self.measures_with_sufficient_data(subcategory:, school:, academic_year:)
subcategory.measures.select do |measure|
sufficient_data?(measure: measure, school: school, academic_year: academic_year)
end
end
def self.responses_for_measure(measure:, school:, academic_year:)
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_all_thresholds = meets_teacher_threshold && meets_student_threshold
if meets_all_thresholds
SurveyItemResponse.for_measure(measure, school, academic_year)
elsif meets_teacher_threshold
SurveyItemResponse.teacher_responses_for_measure(measure, school, academic_year)
elsif meets_student_threshold
SurveyItemResponse.student_responses_for_measure(measure, school, academic_year)
end
end
def self.score_for_measure(measure:, school:, academic_year:)
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
survey_item_responses = responses_for_measure(measure: measure, school: school, academic_year: academic_year)
score_for_measure = survey_item_responses.average(:likert_score) unless survey_item_responses.nil?
Score.new(score_for_measure, meets_teacher_threshold, meets_student_threshold)
end
def self.sufficient_data?(measure:, school:, academic_year:)
meets_teacher_threshold = teacher_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_student_threshold = student_sufficient_data? measure: measure, school: school, academic_year: academic_year
meets_teacher_threshold || meets_student_threshold
end
scope :for_measure, lambda { |measure, school, academic_year|
joins(:survey_item)
.where('survey_items.measure': measure)
.where(school: school, academic_year: academic_year)
}
scope :for_measures, lambda { |measures, school, academic_year|
joins(:survey_item)
.where('survey_items.measure': measures)
.where(school: school, academic_year: academic_year)
}
scope :teacher_responses_for_measure, lambda { |measure, school, academic_year|
for_measure(measure, school, academic_year)
.where("survey_items.survey_item_id LIKE 't-%'")
}
scope :teacher_responses_for_measures, lambda { |measures, school, academic_year|
for_measures(measures, school, academic_year)
.where("survey_items.survey_item_id LIKE 't-%'")
}
scope :student_responses_for_measure, lambda { |measure, school, academic_year|
for_measure(measure, school, academic_year)
.where("survey_items.survey_item_id LIKE 's-%'")
}
scope :student_responses_for_measures, lambda { |measures, school, academic_year|
for_measures(measures, school, academic_year)
.where("survey_items.survey_item_id LIKE 's-%'")
}
def self.student_sufficient_data?(measure:, school:, academic_year:)
if measure.includes_student_survey_items?
student_survey_item_responses = SurveyItemResponse.student_responses_for_measure(measure, school, academic_year)
average_number_of_survey_item_responses = student_survey_item_responses.count / measure.student_survey_items.count
meets_student_threshold = average_number_of_survey_item_responses >= STUDENT_RESPONSE_THRESHOLD
end
!!meets_student_threshold
end
def self.teacher_sufficient_data?(measure:, school:, academic_year:)
if measure.includes_teacher_survey_items?
teacher_survey_item_responses = SurveyItemResponse.teacher_responses_for_measure(measure, school, academic_year)
average_number_of_survey_item_responses = teacher_survey_item_responses.count / measure.teacher_survey_items.count
meets_teacher_threshold = average_number_of_survey_item_responses >= TEACHER_RESPONSE_THRESHOLD
end
!!meets_teacher_threshold
end
private_class_method :measures_with_sufficient_data
end