mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
feat: Update cleaner and uploader to load gender data from parent surveys
Implement graph views for parent gender data
This commit is contained in:
parent
7ebe8234cb
commit
9d8543afae
16 changed files with 262 additions and 98 deletions
|
|
@ -3,4 +3,5 @@ class Parent < ApplicationRecord
|
||||||
has_many :parent_languages
|
has_many :parent_languages
|
||||||
has_and_belongs_to_many :languages, join_table: :parent_languages
|
has_and_belongs_to_many :languages, join_table: :parent_languages
|
||||||
has_and_belongs_to_many :races, join_table: :parent_races
|
has_and_belongs_to_many :races, join_table: :parent_races
|
||||||
|
has_and_belongs_to_many :genders, join_table: :parent_genders
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,18 @@ class SurveyItemResponse < ActiveRecord::Base
|
||||||
else
|
else
|
||||||
race.map(&:id)
|
race.map(&:id)
|
||||||
end
|
end
|
||||||
SurveyItemResponse.joins("JOIN parent_races on survey_item_responses.parent_id = parent_races.parent_id JOIN parents on parents.id = parent_races.parent_id").where(
|
|
||||||
school:, academic_year:, survey_item: survey_items
|
SurveyItemResponse.joins([parent: :races]).where(races: { id: }, survey_item: survey_items, school:, academic_year:).group(:survey_item).having("count(*) >= 10").average(:likert_score)
|
||||||
).where("parent_races.race_id": id).group(:survey_item).having("count(*) >= 10").average(:likert_score)
|
}
|
||||||
|
|
||||||
|
scope :averages_for_parent_gender, lambda { |survey_items, school, academic_year, gender|
|
||||||
|
id = if gender.instance_of? ::Gender
|
||||||
|
gender.id
|
||||||
|
else
|
||||||
|
gender.map(&:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
SurveyItemResponse.joins([parent: :genders]).where(genders: { id: }, survey_item: survey_items, school:, academic_year:).group(:survey_item).having("count(*) >= 10").where.not(parent: nil).average(:likert_score)
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :averages_for_language, lambda { |survey_items, school, academic_year, designations|
|
scope :averages_for_language, lambda { |survey_items, school, academic_year, designations|
|
||||||
|
|
|
||||||
78
app/presenters/analyze/graph/column/parent/base.rb
Normal file
78
app/presenters/analyze/graph/column/parent/base.rb
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Analyze
|
||||||
|
module Graph
|
||||||
|
module Column
|
||||||
|
module Parent
|
||||||
|
class Base
|
||||||
|
def label
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def basis
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_irrelevancy_message?(construct:)
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_insufficient_data_message?(construct:, school:, academic_years:)
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def insufficiency_message
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def score(construct:, school:, academic_year:)
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def type
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def n_size(construct:, school:, academic_year:)
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_insufficient_data_message?(construct:, school:, academic_years:)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def basis
|
||||||
|
"parent surveys"
|
||||||
|
end
|
||||||
|
|
||||||
|
def type
|
||||||
|
:parent
|
||||||
|
end
|
||||||
|
|
||||||
|
def bubble_up_averages(construct:, averages:)
|
||||||
|
name = construct.class.name.downcase
|
||||||
|
send("#{name}_bubble_up_averages", construct:, averages:)
|
||||||
|
end
|
||||||
|
|
||||||
|
def measure_bubble_up_averages(construct:, averages:)
|
||||||
|
construct.parent_scales.map do |scale|
|
||||||
|
scale_bubble_up_averages(construct: scale, averages:)
|
||||||
|
end.remove_blanks.average
|
||||||
|
end
|
||||||
|
|
||||||
|
def scale_bubble_up_averages(construct:, averages:)
|
||||||
|
construct.survey_items.map do |survey_item|
|
||||||
|
averages[survey_item]
|
||||||
|
end.remove_blanks.average
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_irrelevancy_message?(construct:)
|
||||||
|
return false if @show_irrelevancy_message == false
|
||||||
|
|
||||||
|
construct.survey_items.parent_survey_items.count.zero?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
39
app/presenters/analyze/graph/column/parent/gender.rb
Normal file
39
app/presenters/analyze/graph/column/parent/gender.rb
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Analyze
|
||||||
|
module Graph
|
||||||
|
module Column
|
||||||
|
module Parent
|
||||||
|
class Gender < Base
|
||||||
|
attr_reader :genders, :label
|
||||||
|
|
||||||
|
def initialize(genders:, label:, show_irrelevancy_message:)
|
||||||
|
@genders = genders
|
||||||
|
@label = label
|
||||||
|
@show_irrelevancy_message = show_irrelevancy_message
|
||||||
|
end
|
||||||
|
|
||||||
|
def n_size(construct:, school:, academic_year:)
|
||||||
|
id = if genders.instance_of? ::Gender
|
||||||
|
genders.id
|
||||||
|
else
|
||||||
|
genders.map(&:id)
|
||||||
|
end
|
||||||
|
SurveyItemResponse.joins([parent: :genders]).where(genders: { id: }, survey_item: construct.parent_survey_items, school:, academic_year:).select(:parent_id).distinct.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def score(construct:, school:, academic_year:)
|
||||||
|
return Score::NIL_SCORE if n_size(construct:, school:, academic_year:) < 10
|
||||||
|
|
||||||
|
averages = SurveyItemResponse.averages_for_parent_gender(construct.parent_survey_items, school, academic_year, genders)
|
||||||
|
average = bubble_up_averages(construct:, averages:).round(2)
|
||||||
|
Score.new(average:,
|
||||||
|
meets_teacher_threshold: false,
|
||||||
|
meets_student_threshold: true,
|
||||||
|
meets_admin_data_threshold: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -4,7 +4,7 @@ module Analyze
|
||||||
module Graph
|
module Graph
|
||||||
module Column
|
module Column
|
||||||
module Parent
|
module Parent
|
||||||
class Language < ColumnBase
|
class Language < Base
|
||||||
attr_reader :language, :label
|
attr_reader :language, :label
|
||||||
|
|
||||||
def initialize(languages:, label:, show_irrelevancy_message:)
|
def initialize(languages:, label:, show_irrelevancy_message:)
|
||||||
|
|
@ -13,18 +13,6 @@ module Analyze
|
||||||
@show_irrelevancy_message = show_irrelevancy_message
|
@show_irrelevancy_message = show_irrelevancy_message
|
||||||
end
|
end
|
||||||
|
|
||||||
def basis
|
|
||||||
"parent surveys"
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_insufficient_data_message?(construct:, school:, academic_years:)
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def type
|
|
||||||
:parent
|
|
||||||
end
|
|
||||||
|
|
||||||
def n_size(construct:, school:, academic_year:)
|
def n_size(construct:, school:, academic_year:)
|
||||||
SurveyItemResponse.joins([parent: :languages]).where(languages: { designation: designations }, survey_item: construct.parent_survey_items, school:, academic_year:).select(:parent_id).distinct.count
|
SurveyItemResponse.joins([parent: :languages]).where(languages: { designation: designations }, survey_item: construct.parent_survey_items, school:, academic_year:).select(:parent_id).distinct.count
|
||||||
end
|
end
|
||||||
|
|
@ -44,29 +32,6 @@ module Analyze
|
||||||
def designations
|
def designations
|
||||||
language.map(&:designation)
|
language.map(&:designation)
|
||||||
end
|
end
|
||||||
|
|
||||||
def bubble_up_averages(construct:, averages:)
|
|
||||||
name = construct.class.name.downcase
|
|
||||||
send("#{name}_bubble_up_averages", construct:, averages:)
|
|
||||||
end
|
|
||||||
|
|
||||||
def measure_bubble_up_averages(construct:, averages:)
|
|
||||||
construct.parent_scales.map do |scale|
|
|
||||||
scale_bubble_up_averages(construct: scale, averages:)
|
|
||||||
end.remove_blanks.average
|
|
||||||
end
|
|
||||||
|
|
||||||
def scale_bubble_up_averages(construct:, averages:)
|
|
||||||
construct.survey_items.map do |survey_item|
|
|
||||||
averages[survey_item]
|
|
||||||
end.remove_blanks.average
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_irrelevancy_message?(construct:)
|
|
||||||
return false if @show_irrelevancy_message == false
|
|
||||||
|
|
||||||
construct.survey_items.parent_survey_items.count.zero?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ module Analyze
|
||||||
module Graph
|
module Graph
|
||||||
module Column
|
module Column
|
||||||
module Parent
|
module Parent
|
||||||
class Race < ColumnBase
|
class Race < Base
|
||||||
attr_reader :race, :label
|
attr_reader :race, :label
|
||||||
|
|
||||||
def initialize(races:, label:, show_irrelevancy_message:)
|
def initialize(races:, label:, show_irrelevancy_message:)
|
||||||
|
|
@ -13,18 +13,6 @@ module Analyze
|
||||||
@show_irrelevancy_message = show_irrelevancy_message
|
@show_irrelevancy_message = show_irrelevancy_message
|
||||||
end
|
end
|
||||||
|
|
||||||
def basis
|
|
||||||
"parent surveys"
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_insufficient_data_message?(construct:, school:, academic_years:)
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def type
|
|
||||||
:parent
|
|
||||||
end
|
|
||||||
|
|
||||||
def n_size(construct:, school:, academic_year:)
|
def n_size(construct:, school:, academic_year:)
|
||||||
designation = if race.instance_of? ::Race
|
designation = if race.instance_of? ::Race
|
||||||
race.designation
|
race.designation
|
||||||
|
|
@ -44,29 +32,6 @@ module Analyze
|
||||||
meets_student_threshold: true,
|
meets_student_threshold: true,
|
||||||
meets_admin_data_threshold: false)
|
meets_admin_data_threshold: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def bubble_up_averages(construct:, averages:)
|
|
||||||
name = construct.class.name.downcase
|
|
||||||
send("#{name}_bubble_up_averages", construct:, averages:)
|
|
||||||
end
|
|
||||||
|
|
||||||
def measure_bubble_up_averages(construct:, averages:)
|
|
||||||
construct.parent_scales.map do |scale|
|
|
||||||
scale_bubble_up_averages(construct: scale, averages:)
|
|
||||||
end.remove_blanks.average
|
|
||||||
end
|
|
||||||
|
|
||||||
def scale_bubble_up_averages(construct:, averages:)
|
|
||||||
construct.survey_items.map do |survey_item|
|
|
||||||
averages[survey_item]
|
|
||||||
end.remove_blanks.average
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_irrelevancy_message?(construct:)
|
|
||||||
return false if @show_irrelevancy_message == false
|
|
||||||
|
|
||||||
construct.survey_items.parent_survey_items.count.zero?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
42
app/presenters/analyze/graph/parents_by_gender.rb
Normal file
42
app/presenters/analyze/graph/parents_by_gender.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Analyze
|
||||||
|
module Graph
|
||||||
|
class ParentsByGender
|
||||||
|
def to_s
|
||||||
|
"Parents by Gender"
|
||||||
|
end
|
||||||
|
|
||||||
|
def slug
|
||||||
|
"parents-by-gender"
|
||||||
|
end
|
||||||
|
|
||||||
|
def columns
|
||||||
|
[].tap do |array|
|
||||||
|
Gender.all.each do |gender|
|
||||||
|
label = if gender.designation.match(/\or\s/i)
|
||||||
|
[gender.designation.split("or").first.squish]
|
||||||
|
else
|
||||||
|
gender.designation.split(" ", 2).compact
|
||||||
|
end
|
||||||
|
|
||||||
|
array << Analyze::Graph::Column::Parent::Gender.new(genders: gender, label:, show_irrelevancy_message: false)
|
||||||
|
end
|
||||||
|
array << Analyze::Graph::Column::Parent::Gender.new(genders: Gender.all, label: ["All Parent"], show_irrelevancy_message: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def source
|
||||||
|
Analyze::Source::SurveyData.new(slices: nil, graph: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def slice
|
||||||
|
Analyze::Slice::ParentsByGroup.new(graph: self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def group
|
||||||
|
Analyze::Group::Base.new(name: "Student Gender", slug: "student-gender", graph: self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -166,7 +166,8 @@ module Analyze
|
||||||
"students-by-sped" => Analyze::Graph::StudentsBySped.new(speds: selected_speds),
|
"students-by-sped" => Analyze::Graph::StudentsBySped.new(speds: selected_speds),
|
||||||
"students-by-ell" => Analyze::Graph::StudentsByEll.new(ells: selected_ells),
|
"students-by-ell" => Analyze::Graph::StudentsByEll.new(ells: selected_ells),
|
||||||
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
||||||
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new }
|
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new,
|
||||||
|
"parents-by-gender" => Analyze::Graph::ParentsByGender.new }
|
||||||
end
|
end
|
||||||
|
|
||||||
# The last item will per slice type will be selected as the default slice
|
# The last item will per slice type will be selected as the default slice
|
||||||
|
|
@ -183,7 +184,8 @@ module Analyze
|
||||||
"students-by-sped" => nil,
|
"students-by-sped" => nil,
|
||||||
"students-by-ell" => nil,
|
"students-by-ell" => nil,
|
||||||
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
"parents-by-race" => Analyze::Graph::ParentsByRace.new,
|
||||||
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new }
|
"parents-by-language" => Analyze::Graph::ParentsByLanguage.new,
|
||||||
|
"parents-by-gender" => Analyze::Graph::ParentsByGender.new }
|
||||||
end
|
end
|
||||||
|
|
||||||
def graphs
|
def graphs
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class Cleaner
|
||||||
|
|
||||||
headers = headers.to_set
|
headers = headers.to_set
|
||||||
headers = headers.merge(Set.new(["Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count",
|
headers = headers.merge(Set.new(["Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count",
|
||||||
"Race", "Gender", "Raw Housing Status", "Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents"])).to_a
|
"Race", "Gender", "Raw Housing Status", "Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents", "Declared Genders of Children from Parents"])).to_a
|
||||||
filtered_headers = include_all_headers(headers:)
|
filtered_headers = include_all_headers(headers:)
|
||||||
filtered_headers = remove_unwanted_headers(headers: filtered_headers)
|
filtered_headers = remove_unwanted_headers(headers: filtered_headers)
|
||||||
log_headers = (filtered_headers + ["Valid Duration?", "Valid Progress?", "Valid Grade?",
|
log_headers = (filtered_headers + ["Valid Duration?", "Valid Progress?", "Valid Grade?",
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class SurveyItemValues
|
||||||
row["Housing Status"] = housing
|
row["Housing Status"] = housing
|
||||||
row["Home Languages"] = languages.join(",")
|
row["Home Languages"] = languages.join(",")
|
||||||
row["Declared Races of Children from Parents"] = races_of_children.join(",")
|
row["Declared Races of Children from Parents"] = races_of_children.join(",")
|
||||||
|
row["Declared Genders of Children from Parents"] = genders_of_children.join(",")
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalize_headers(headers:)
|
def normalize_headers(headers:)
|
||||||
|
|
@ -146,6 +147,25 @@ class SurveyItemValues
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def genders_of_children
|
||||||
|
@genders_of_children ||= [].tap do |gender_codes|
|
||||||
|
matches = headers.select do |header|
|
||||||
|
# Explanation:
|
||||||
|
# ^: Start of the string.
|
||||||
|
# (?!.*text): Negative lookahead — ensures that the word text does not appear anywhere in the string.
|
||||||
|
# .*?: Lazily match any characters (to get to the word gender).
|
||||||
|
# gender: Match the word gender
|
||||||
|
header.match(/^(?!.*text).*?gender/i)
|
||||||
|
end
|
||||||
|
|
||||||
|
matches.each do |match|
|
||||||
|
code = row[match]&.strip
|
||||||
|
gender_codes << Gender.qualtrics_code_from(code).to_i unless code.nil?
|
||||||
|
end
|
||||||
|
gender_codes << 99 if gender_codes.empty?
|
||||||
|
end.uniq.sort
|
||||||
|
end
|
||||||
|
|
||||||
def races
|
def races
|
||||||
@races ||= begin
|
@races ||= begin
|
||||||
race_codes ||= self_report = value_from(pattern: /Race\s*self\s*report/i)
|
race_codes ||= self_report = value_from(pattern: /Race\s*self\s*report/i)
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,10 @@ class SurveyResponsesDataLoader
|
||||||
tmp_races = row.races_of_children.map { |race| races[race] }.reject(&:nil?)
|
tmp_races = row.races_of_children.map { |race| races[race] }.reject(&:nil?)
|
||||||
parent.races.concat(tmp_races)
|
parent.races.concat(tmp_races)
|
||||||
|
|
||||||
|
parent.genders.delete_all
|
||||||
|
tmp_genders = row.genders_of_children.map { |race| genders[race] }.reject(&:nil?)
|
||||||
|
parent.genders.concat(tmp_genders)
|
||||||
|
|
||||||
parent.housing = housings[row.housing] if row.housing.present?
|
parent.housing = housings[row.housing] if row.housing.present?
|
||||||
parent.save
|
parent.save
|
||||||
end
|
end
|
||||||
|
|
|
||||||
10
db/migrate/20250523222834_create_parent_genders.rb
Normal file
10
db/migrate/20250523222834_create_parent_genders.rb
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
class CreateParentGenders < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
create_table :parent_genders do |t|
|
||||||
|
t.references :parent, null: false, foreign_key: true
|
||||||
|
t.references :gender, null: false, foreign_key: true
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
13
db/schema.rb
13
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.0].define(version: 2025_05_15_205734) do
|
ActiveRecord::Schema[8.0].define(version: 2025_05_23_222834) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_catalog.plpgsql"
|
enable_extension "pg_catalog.plpgsql"
|
||||||
|
|
||||||
|
|
@ -330,6 +330,15 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_15_205734) do
|
||||||
t.index ["subcategory_id"], name: "index_measures_on_subcategory_id"
|
t.index ["subcategory_id"], name: "index_measures_on_subcategory_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "parent_genders", force: :cascade do |t|
|
||||||
|
t.bigint "parent_id", null: false
|
||||||
|
t.bigint "gender_id", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["gender_id"], name: "index_parent_genders_on_gender_id"
|
||||||
|
t.index ["parent_id"], name: "index_parent_genders_on_parent_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "parent_languages", force: :cascade do |t|
|
create_table "parent_languages", force: :cascade do |t|
|
||||||
t.bigint "parent_id", null: false
|
t.bigint "parent_id", null: false
|
||||||
t.bigint "language_id", null: false
|
t.bigint "language_id", null: false
|
||||||
|
|
@ -543,6 +552,8 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_15_205734) do
|
||||||
add_foreign_key "legacy_school_categories", "legacy_categories", column: "category_id"
|
add_foreign_key "legacy_school_categories", "legacy_categories", column: "category_id"
|
||||||
add_foreign_key "legacy_school_categories", "legacy_schools", column: "school_id"
|
add_foreign_key "legacy_school_categories", "legacy_schools", column: "school_id"
|
||||||
add_foreign_key "measures", "subcategories"
|
add_foreign_key "measures", "subcategories"
|
||||||
|
add_foreign_key "parent_genders", "genders"
|
||||||
|
add_foreign_key "parent_genders", "parents"
|
||||||
add_foreign_key "parent_languages", "languages"
|
add_foreign_key "parent_languages", "languages"
|
||||||
add_foreign_key "parent_languages", "parents"
|
add_foreign_key "parent_languages", "parents"
|
||||||
add_foreign_key "parent_races", "parents"
|
add_foreign_key "parent_races", "parents"
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
StartDate,EndDate,Status,IPAddress,Progress,Duration (in seconds),Finished,RecordedDate,ResponseId,DistributionChannel,UserLanguage,DESE ID,Number of Children,Gender-1,Gender-1_7_TEXT,Race-1,Race-1_7_TEXT,Gender-2,Gender-2_7_TEXT,Race-2,Race-2_7_TEXT,Gender-3,Gender-3_7_TEXT,Race-3,Race-3_7_TEXT,Gender-4,Gender-4_7_TEXT,Race-4,Race-4_7_TEXT,Gender-5,Gender-5_7_TEXT,Race-5,Race-5_7_TEXT,Gender,Gender_7_TEXT,p-scrp-q3,p-scrp-q2,p-valm-q1,p-valm-q2,p-valm-q3,p-valm-q4,p-comm-q1,p-comm-q2,p-comm-q3,p-tcom-q1,P-tcom-q2,p-tcom-q3,p-evnt-q4,p-comm-q4,p-evnt-q3,p-evnt-q1,p-evnt-q2,p-socx-q3,p-socx-q4,p-scrp-q1,p-socx-q1,p-sosu-q1,p-sosu-q2,p-sosu-q3,p-socx-q2,p-sosu-q4,p-phys-q3,p-acpr-q1,p-acpr-q2,p-acpr-q3,p-acpr-q4,p-cure-q1,p-cure-q2,p-cure-q3,p-cure-q4,Housing,Housing_100_TEXT,Employment,Employment_100_TEXT,Caregivers,Caregivers_100_TEXT,Education,Education_100_TEXT,Benefits,Benefits_100_TEXT,Language,Language_100_TEXT,Raw Income,Income,Raw ELL,ELL,Raw SpEd,SpEd,Progress Count
|
StartDate,EndDate,Status,IPAddress,Progress,Duration (in seconds),Finished,RecordedDate,ResponseId,DistributionChannel,UserLanguage,DESE ID,Number of Children,Gender-1,Gender-1_7_TEXT,Race-1,Race-1_7_TEXT,Gender-2,Gender-2_7_TEXT,Race-2,Race-2_7_TEXT,Gender-3,Gender-3_7_TEXT,Race-3,Race-3_7_TEXT,Gender-4,Gender-4_7_TEXT,Race-4,Race-4_7_TEXT,Gender-5,Gender-5_7_TEXT,Race-5,Race-5_7_TEXT,Gender,Gender_7_TEXT,p-scrp-q3,p-scrp-q2,p-valm-q1,p-valm-q2,p-valm-q3,p-valm-q4,p-comm-q1,p-comm-q2,p-comm-q3,p-tcom-q1,P-tcom-q2,p-tcom-q3,p-evnt-q4,p-comm-q4,p-evnt-q3,p-evnt-q1,p-evnt-q2,p-socx-q3,p-socx-q4,p-scrp-q1,p-socx-q1,p-sosu-q1,p-sosu-q2,p-sosu-q3,p-socx-q2,p-sosu-q4,p-phys-q3,p-acpr-q1,p-acpr-q2,p-acpr-q3,p-acpr-q4,p-cure-q1,p-cure-q2,p-cure-q3,p-cure-q4,Housing,Housing_100_TEXT,Employment,Employment_100_TEXT,Caregivers,Caregivers_100_TEXT,Education,Education_100_TEXT,Benefits,Benefits_100_TEXT,Language,Language_100_TEXT,Raw Income,Income,Raw ELL,ELL,Raw SpEd,SpEd,Progress Count
|
||||||
5/1/2024 10:04:34,5/1/2024 10:10:49,0,72.93.86.98,100,374,1,2021-03-31T10:01:36,parent_survey_response_1,email,EN,1500025,1,,,1,,,,,,,,,,,,,,,,,,2,,4,5,5,4,5,5,5,5,5,4,4,5,4,5,3,4,5,4,4,5,5,5,5,5,5,5,1,2,2,2,1,4,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:04:34,5/1/2024 10:10:49,0,72.93.86.98,100,374,1,2021-03-31T10:01:36,parent_survey_response_1,email,EN,1500025,1,,,1,,,,,,,,,,,,,,,,,,2,,4,5,5,4,5,5,5,5,5,4,4,5,4,5,3,4,5,4,4,5,5,5,5,5,5,5,1,2,2,2,1,4,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:03:52,5/1/2024 10:14:42,0,73.69.182.58,100,649,1,2021-04-01T10:01:36,parent_survey_response_2,email,EN,1500025,1,,,,,,,,,,,6,,,,7,,,,,,1,,4,4,5,5,5,5,5,5,5,5,5,5,3,5,4,5,5,5,5,5,4,4,4,4,5,5,1,5,4,5,5,5,5,5,5,1,,99,,2,,3,,1,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:03:52,5/1/2024 10:14:42,0,73.69.182.58,100,649,1,2021-04-01T10:01:36,parent_survey_response_2,email,EN,1500025,1,,,,,,,,,,,6,,,,7,,,,,,1,,4,4,5,5,5,5,5,5,5,5,5,5,3,5,4,5,5,5,5,5,4,4,4,4,5,5,1,5,4,5,5,5,5,5,5,1,,99,,2,,3,,1,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:06:44,5/1/2024 10:15:41,0,50.235.109.170,100,537,1,2021-04-02T10:01:36,parent_survey_response_3,email,EN,1500025,2,2,,4,,2,,"1,5",,,,,,,,,,,,,,2,,5,5,5,4,5,5,5,5,5,4,4,5,4,4,3,4,4,4,4,5,4,4,5,5,2,5,3,4,4,4,4,5,5,5,5,1,,1,,3,,6,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:06:44,5/1/2024 10:15:41,0,50.235.109.170,100,537,1,2021-04-02T10:01:36,parent_survey_response_3,email,EN,1500025,2,1,,4,,2,,"1,5",,,,,,,,,,,,,,2,,5,5,5,4,5,5,5,5,5,4,4,5,4,4,3,4,4,4,4,5,4,4,5,5,2,5,3,4,4,4,4,5,5,5,5,1,,1,,3,,6,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:14:23,5/1/2024 10:22:22,0,73.38.238.192,100,478,1,2021-04-03T10:01:36,parent_survey_response_4,email,EN,1500025,1,,,,,,,,,,,,,,,,,,,,,1,,5,5,5,5,5,5,5,4,5,4,4,4,2,5,4,5,4,5,5,5,3,5,5,5,2,5,1,5,5,5,5,5,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:14:23,5/1/2024 10:22:22,0,73.38.238.192,100,478,1,2021-04-03T10:01:36,parent_survey_response_4,email,EN,1500025,1,3,,7,,,,,,,,,,,,,,,,,,4,,5,5,5,5,5,5,5,4,5,4,4,4,2,5,4,5,4,5,5,5,3,5,5,5,2,5,1,5,5,5,5,5,5,5,5,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:18:39,5/1/2024 10:23:49,0,73.69.158.255,100,310,1,2021-04-04T10:01:36,parent_survey_response_5,email,EN,1500025,2,2,,"1,2,3",,1,,"4,5,8",,,,,,,,,,,,,,2,,5,4,5,5,5,5,1,1,1,1,1,1,3,1,4,4,5,1,1,1,4,1,1,1,4,5,1,5,5,5,5,1,5,1,1,1,,"2,4",,3,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:18:39,5/1/2024 10:23:49,0,73.69.158.255,100,310,1,2021-04-04T10:01:36,parent_survey_response_5,email,EN,1500025,2,2,,"1,2,3",,,,"4,5,8",,,,,,,,,,,,,,2,,5,4,5,5,5,5,1,1,1,1,1,1,3,1,4,4,5,1,1,1,4,1,1,1,4,5,1,5,5,5,5,1,5,1,1,1,,"2,4",,3,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:20:30,5/1/2024 10:25:16,0,73.182.146.201,100,285,1,2021-04-05T10:01:36,parent_survey_response_6,email,EN,1500025,1,,,,,,,,,,,,,,,1,,,,"2,3,4,5,8",,1,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,2,,2,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:20:30,5/1/2024 10:25:16,0,73.182.146.201,100,285,1,2021-04-05T10:01:36,parent_survey_response_6,email,EN,1500025,1,,,,,,,,,,,,,,,1,,,,"2,3,4,5,8",,,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,2,,2,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_7,email,EN,1500025,2,1,,5,,1,,5,,,,,,,,,,,,,,1,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_7,email,EN,1500025,2,6,,5,,,,5,,,,,,,,,,,,,,,,3,3,3,1,3,2,4,2,4,1,1,3,3,4,3,4,1,5,5,4,3,5,4,3,3,1,3,5,5,4,5,4,4,5,4,1,,1,,2,,5,,2,,1,,,Economically Disadvantaged - N,,Not ELL,,Not Special Education,34
|
||||||
5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_8,email,EN,1500025,2,1,,5,,1,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
5/1/2024 10:14:01,5/1/2024 10:27:19,0,209.107.182.203,100,798,1,2021-04-06T10:01:36,parent_survey_response_8,email,EN,1500025,2,Prefer not to disclose,,5,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
|
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ def reads_headers_from_raw_csv(processed_data)
|
||||||
"s-grit-q1", "s-grit-q2", "s-grit-q3", "s-grit-q4", "s-expa-q1", "s-poaf-q1", "s-poaf-q2", "s-poaf-q3",
|
"s-grit-q1", "s-grit-q2", "s-grit-q3", "s-grit-q4", "s-expa-q1", "s-poaf-q1", "s-poaf-q2", "s-poaf-q3",
|
||||||
"s-poaf-q4", "s-tint-q1-1", "s-tint-q2-1", "s-tint-q3-1", "s-tint-q4-1", "s-tint-q5-1", "s-acpr-q1-1",
|
"s-poaf-q4", "s-tint-q1-1", "s-tint-q2-1", "s-tint-q3-1", "s-tint-q4-1", "s-tint-q5-1", "s-acpr-q1-1",
|
||||||
"s-acpr-q2-1", "s-acpr-q3-1", "s-acpr-q4-1", "s-peff-q1-1", "s-peff-q2-1", "s-peff-q3-1", "s-peff-q4-1",
|
"s-acpr-q2-1", "s-acpr-q3-1", "s-acpr-q4-1", "s-peff-q1-1", "s-peff-q2-1", "s-peff-q3-1", "s-peff-q4-1",
|
||||||
"s-peff-q5-1", "s-peff-q6-1", "Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", "Housing Status", "Raw Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents"].to_set.sort
|
"s-peff-q5-1", "s-peff-q6-1", "Raw Income", "Income", "Raw ELL", "ELL", "Raw SpEd", "SpEd", "Progress Count", "Housing Status", "Raw Housing Status", "Home Language", "Home Languages", "Declared Races of Children from Parents", "Declared Genders of Children from Parents"].to_set.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def invalid_rows_are_rejected_for_the_correct_reasons(data)
|
def invalid_rows_are_rejected_for_the_correct_reasons(data)
|
||||||
|
|
|
||||||
|
|
@ -129,12 +129,12 @@ describe SurveyResponsesDataLoader do
|
||||||
let(:unknown_race) { create(:race, qualtrics_code: 99, designation: "Race/Ethnicity Not Listed") }
|
let(:unknown_race) { create(:race, qualtrics_code: 99, designation: "Race/Ethnicity Not Listed") }
|
||||||
let(:multiracial) { create(:race, qualtrics_code: 100, designation: "Multiracial") }
|
let(:multiracial) { create(:race, qualtrics_code: 100, designation: "Multiracial") }
|
||||||
|
|
||||||
let(:languages){
|
let(:languages) do
|
||||||
create(:language, designation: "English")
|
create(:language, designation: "English")
|
||||||
create(:language, designation: "Spanish")
|
create(:language, designation: "Spanish")
|
||||||
create(:language, designation: "Portuguese")
|
create(:language, designation: "Portuguese")
|
||||||
create(:language, designation: "Unknown")
|
create(:language, designation: "Unknown")
|
||||||
}
|
end
|
||||||
|
|
||||||
let(:setup) do
|
let(:setup) do
|
||||||
ay_2020_21
|
ay_2020_21
|
||||||
|
|
@ -277,6 +277,10 @@ describe SurveyResponsesDataLoader do
|
||||||
it "loads the correct set of races for parents" do
|
it "loads the correct set of races for parents" do
|
||||||
assigns_races_to_parents
|
assigns_races_to_parents
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "loads the correct set of genders for parents" do
|
||||||
|
assigns_genders_to_parents
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -470,18 +474,18 @@ def assigns_races_to_students
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def assigns_races_to_parents
|
def assigns_races_to_parents
|
||||||
results = {
|
results = {
|
||||||
"parent_survey_response_1" => [american_indian],
|
"parent_survey_response_1" => [american_indian],
|
||||||
"parent_survey_response_2" => [unknown_race],
|
"parent_survey_response_2" => [unknown_race],
|
||||||
"parent_survey_response_3" => [american_indian, latinx, white, multiracial],
|
"parent_survey_response_3" => [american_indian, latinx, white, multiracial],
|
||||||
"parent_survey_response_4" => [unknown_race],
|
"parent_survey_response_4" => [unknown_race],
|
||||||
"parent_survey_response_5" => [american_indian, asian, black, latinx, white, middle_eastern,
|
"parent_survey_response_5" => [american_indian, asian, black, latinx, white, middle_eastern,
|
||||||
multiracial],
|
multiracial],
|
||||||
"parent_survey_response_6" => [american_indian, asian, black, latinx, white, middle_eastern,
|
"parent_survey_response_6" => [american_indian, asian, black, latinx, white, middle_eastern,
|
||||||
multiracial],
|
multiracial],
|
||||||
"parent_survey_response_7" => [white] }
|
"parent_survey_response_7" => [white]
|
||||||
|
}
|
||||||
|
|
||||||
results.each do |key, value|
|
results.each do |key, value|
|
||||||
race = SurveyItemResponse.find_by_response_id(key).parent.races.to_a
|
race = SurveyItemResponse.find_by_response_id(key).parent.races.to_a
|
||||||
|
|
@ -489,3 +493,17 @@ def assigns_races_to_parents
|
||||||
expect(race).to eq value
|
expect(race).to eq value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assigns_genders_to_parents
|
||||||
|
results = { "parent_survey_response_1" => [male],
|
||||||
|
"parent_survey_response_2" => [female],
|
||||||
|
"parent_survey_response_3" => [female, male],
|
||||||
|
"parent_survey_response_4" => [non_binary],
|
||||||
|
"parent_survey_response_5" => [male],
|
||||||
|
"parent_survey_response_6" => [unknown_gender] }
|
||||||
|
# "parent_survey_response_7" => [non_binary] }
|
||||||
|
|
||||||
|
results.each do |key, value|
|
||||||
|
expect(SurveyItemResponse.where(response_id: key).first.parent.genders).to eq value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue