mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-08 23:18:18 -07:00
Update demographics table with lanugage options Create a lanugage table to hold the new languages Update the demographic loader to input languages into the database Update the cleaner to read the language column Update the parent table to hold a reference to a language Update the data uploader script to read the language from the csv and update the language information for any parent items that already exist (or create database entries if none already exist) update the analyze interface to add controls for selecting ‘parents by group’ and a dropdown for ‘parent by language’ Update the analyze controller to read the parent-by-group parameter Create a graph for the parent-by-group view Bubble up averages for language calculations. Make sure n-size only counts responses for a given measure.
200 lines
5.2 KiB
Ruby
200 lines
5.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class SurveyResponsesDataLoader
|
|
BATCH_SIZE = 200
|
|
def load_data(filepath:)
|
|
File.open(filepath) do |file|
|
|
headers = file.first
|
|
headers_array = CSV.parse(headers).first
|
|
all_survey_items = survey_items(headers:)
|
|
|
|
file.lazy.each_slice(BATCH_SIZE) do |lines|
|
|
survey_item_responses = CSV.parse(lines.join, headers:).map do |row|
|
|
process_row(row: SurveyItemValues.new(row:, headers: headers_array, survey_items: all_survey_items, schools:,
|
|
academic_years:))
|
|
end
|
|
|
|
SurveyItemResponse.import(
|
|
survey_item_responses.compact.flatten,
|
|
batch_size: BATCH_SIZE,
|
|
on_duplicate_key_update: :all
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def from_file(file:)
|
|
headers = file.gets
|
|
headers_array = CSV.parse(headers).first
|
|
all_survey_items = survey_items(headers:)
|
|
|
|
survey_item_responses = []
|
|
row_count = 0
|
|
until file.eof?
|
|
line = file.gets
|
|
next unless line.present?
|
|
|
|
CSV.parse(line, headers:).map do |row|
|
|
survey_item_responses << process_row(row: SurveyItemValues.new(row:, headers: headers_array,
|
|
survey_items: all_survey_items, schools:, academic_years:))
|
|
end
|
|
|
|
row_count += 1
|
|
next unless row_count == BATCH_SIZE
|
|
|
|
SurveyItemResponse.import(
|
|
survey_item_responses.compact.flatten,
|
|
batch_size: BATCH_SIZE,
|
|
on_duplicate_key_update: :all
|
|
)
|
|
survey_item_responses = []
|
|
row_count = 0
|
|
end
|
|
|
|
SurveyItemResponse.import(
|
|
survey_item_responses.compact.flatten,
|
|
batch_size: BATCH_SIZE,
|
|
on_duplicate_key_update: :all
|
|
)
|
|
end
|
|
|
|
private
|
|
|
|
def schools
|
|
@schools ||= School.by_dese_id
|
|
end
|
|
|
|
def genders
|
|
@genders ||= Gender.by_qualtrics_code
|
|
end
|
|
|
|
def races
|
|
@races ||= Race.by_qualtrics_code
|
|
end
|
|
|
|
def incomes
|
|
@incomes ||= Income.by_slug
|
|
end
|
|
|
|
def ells
|
|
@ells ||= Ell.by_designation
|
|
end
|
|
|
|
def speds
|
|
@speds ||= Sped.by_designation
|
|
end
|
|
|
|
def academic_years
|
|
@academic_years ||= AcademicYear.all
|
|
end
|
|
|
|
def process_row(row:)
|
|
return unless row.dese_id?
|
|
return unless row.school.present?
|
|
|
|
process_survey_items(row:)
|
|
end
|
|
|
|
def languages
|
|
@languages ||= Language.by_designation
|
|
end
|
|
|
|
def housings
|
|
@housings ||= Housing.by_designation
|
|
end
|
|
|
|
def process_survey_items(row:)
|
|
student = nil
|
|
parent = nil
|
|
if row.respondent_type == :student
|
|
student = Student.find_or_create_by(response_id: row.response_id, lasid: row.lasid)
|
|
student.races.delete_all
|
|
tmp_races = row.races.map { |race| races[race] }.reject(&:nil?)
|
|
student.races += tmp_races
|
|
end
|
|
|
|
if row.respondent_type == :parent
|
|
parent = Parent.find_or_create_by(response_id: row.response_id)
|
|
parent.number_of_children = row.number_of_children
|
|
tmp_languages = row.languages.map { |language| languages[language] }.reject(&:nil?)
|
|
parent.languages.delete_all
|
|
parent.languages.concat(tmp_languages)
|
|
parent.housing = housings[row.housing] if row.housing.present?
|
|
parent.save
|
|
end
|
|
|
|
row
|
|
.survey_items
|
|
.map do |survey_item|
|
|
likert_score = row.likert_score(survey_item_id: survey_item.survey_item_id) || next
|
|
|
|
unless likert_score.valid_likert_score?
|
|
puts("Response ID: #{row.response_id}, Likert score: #{likert_score} rejected") unless likert_score == "NA"
|
|
next
|
|
end
|
|
|
|
response = row.survey_item_response(survey_item:)
|
|
create_or_update_response(survey_item_response: response, likert_score:, row:, survey_item:, student:, parent:)
|
|
end
|
|
.compact
|
|
end
|
|
|
|
def create_or_update_response(survey_item_response:, likert_score:, row:, survey_item:, student:, parent:)
|
|
gender = genders[row.gender]
|
|
grade = row.grade
|
|
income = incomes[row.income.parameterize]
|
|
ell = ells[row.ell]
|
|
sped = speds[row.sped]
|
|
|
|
if survey_item_response.present?
|
|
survey_item_response.likert_score = likert_score
|
|
survey_item_response.grade = grade
|
|
survey_item_response.gender = gender
|
|
survey_item_response.recorded_date = row.recorded_date
|
|
survey_item_response.income = income
|
|
survey_item_response.ell = ell
|
|
survey_item_response.sped = sped
|
|
survey_item_response.student = student
|
|
survey_item_response.parent = parent
|
|
|
|
survey_item_response
|
|
else
|
|
SurveyItemResponse.new(
|
|
response_id: row.response_id,
|
|
academic_year: row.academic_year,
|
|
school: row.school,
|
|
survey_item:,
|
|
likert_score:,
|
|
grade:,
|
|
gender:,
|
|
recorded_date: row.recorded_date,
|
|
income:,
|
|
ell:,
|
|
sped:,
|
|
student:,
|
|
parent:
|
|
)
|
|
end
|
|
end
|
|
|
|
def survey_items(headers:)
|
|
SurveyItem.where(survey_item_id: get_survey_item_ids_from_headers(headers:))
|
|
end
|
|
|
|
def get_survey_item_ids_from_headers(headers:)
|
|
CSV
|
|
.parse(headers)
|
|
.first
|
|
.filter(&:present?)
|
|
.map(&:downcase)
|
|
.filter { |header| header.start_with?("t-", "s-", "p-") }
|
|
end
|
|
end
|
|
|
|
module StringMonkeyPatches
|
|
def valid_likert_score?
|
|
to_i.between?(1, 5)
|
|
end
|
|
end
|
|
|
|
String.include(StringMonkeyPatches)
|