Create gender class. Load genders to database from demographics file

pull/1/head
rebuilt 3 years ago
parent f4e2e6ca83
commit 8cdd1b6285

@ -95,6 +95,15 @@ class AnalyzeController < SqmApplicationController
@sources = [Analyze::Source::SurveyData.new(slices:)] @sources = [Analyze::Source::SurveyData.new(slices:)]
end end
def slice
slice_param = params[:slice]
slices.each do |slice|
@slice = slice if slice.slug == slice_param
end
@slice ||= slices.first
end
def slices def slices
students_and_teachers = Analyze::Slice::StudentsAndTeachers.new students_and_teachers = Analyze::Slice::StudentsAndTeachers.new
students_by_group = Analyze::Slice::StudentsByGroup.new(races:, grades:) students_by_group = Analyze::Slice::StudentsByGroup.new(races:, grades:)
@ -110,7 +119,7 @@ class AnalyzeController < SqmApplicationController
end end
def groups def groups
@groups = [Analyze::Group::Race.new, Analyze::Group::Grade.new] @groups = [Analyze::Group::Race.new, Analyze::Group::Grade.new, Analyze::Group::Gender.new]
end end
def selected_grades def selected_grades
@ -139,12 +148,7 @@ class AnalyzeController < SqmApplicationController
end.keys end.keys
end end
def slice def genders
slice_param = params[:slice] @genders ||= Gender.all
slices.each do |slice|
@slice = slice if slice.slug == slice_param
end
@slice ||= slices.first
end end
end end

@ -0,0 +1,2 @@
class Gender < ApplicationRecord
end

@ -0,0 +1,13 @@
module Analyze
module Group
class Gender
def name
'Gender'
end
def slug
'gender'
end
end
end
end

@ -5,17 +5,30 @@ require 'csv'
class DemographicLoader class DemographicLoader
def self.load_data(filepath:) def self.load_data(filepath:)
CSV.parse(File.read(filepath), headers: true) do |row| CSV.parse(File.read(filepath), headers: true) do |row|
qualtrics_code = row['Race Qualtrics Code'].to_i process_race(row:)
designation = row['Race/Ethnicity'] process_gender(row:)
next unless qualtrics_code && designation
if qualtrics_code.between?(6, 7)
UnknownRace.new(qualtrics_code:, designation:)
else
KnownRace.new(qualtrics_code:, designation:)
end
end end
end end
def self.process_race(row:)
qualtrics_code = row['Race Qualtrics Code'].to_i
designation = row['Race/Ethnicity']
return unless qualtrics_code && designation
if qualtrics_code.between?(6, 7)
UnknownRace.new(qualtrics_code:, designation:)
else
KnownRace.new(qualtrics_code:, designation:)
end
end
def self.process_gender(row:)
qualtrics_code = row['Gender Qualtrics Code'].to_i
designation = row['Sex/Gender']
return unless qualtrics_code && designation
Gender.find_or_create_by!(qualtrics_code:, designation:)
end
end end
class KnownRace class KnownRace

@ -1,8 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
# SurveyItemResponse.where(student: StudentRace.where(race: Race.find_by_qualtrics_code(8)).limit(10).map(&:student)).count
# TODO: figure out why earlier years don't have races attached
require 'csv' require 'csv'
class StudentLoader class StudentLoader

@ -1,6 +1,6 @@
Race Qualtrics Code,Race/Ethnicity,Gender Qualtrics Code,Sex/Gender Race Qualtrics Code,Race/Ethnicity,Gender Qualtrics Code,Sex/Gender
1,American Indian or Alaskan Native,1,Male 1,American Indian or Alaskan Native,2,Male
2,Asian or Pacific Islander,2,Female 2,Asian or Pacific Islander,1,Female
3,Black or African American,3,Another gender or gender identity not listed above 3,Black or African American,3,Another gender or gender identity not listed above
4,Hispanic or Latinx,4,Non-Binary 4,Hispanic or Latinx,4,Non-Binary
5,White or Caucasian,, 5,White or Caucasian,,

1 Race Qualtrics Code Race/Ethnicity Gender Qualtrics Code Sex/Gender
2 1 American Indian or Alaskan Native 1 2 Male
3 2 Asian or Pacific Islander 2 1 Female
4 3 Black or African American 3 Another gender or gender identity not listed above
5 4 Hispanic or Latinx 4 Non-Binary
6 5 White or Caucasian

File diff suppressed because it is too large Load Diff

@ -0,0 +1,10 @@
class CreateGenders < ActiveRecord::Migration[7.0]
def change
create_table :genders do |t|
t.integer :qualtrics_code
t.string :designation
t.timestamps
end
end
end

@ -0,0 +1,5 @@
class AddGenderToStudent < ActiveRecord::Migration[7.0]
def change
add_reference :students, :gender, foreign_key: true
end
end

@ -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[7.0].define(version: 2022_10_15_023621) do ActiveRecord::Schema[7.0].define(version: 2022_10_19_234615) 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_stat_statements" enable_extension "pg_stat_statements"
enable_extension "plpgsql" enable_extension "plpgsql"
@ -70,6 +70,13 @@ ActiveRecord::Schema[7.0].define(version: 2022_10_15_023621) do
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
end end
create_table "genders", force: :cascade do |t|
t.integer "qualtrics_code"
t.string "designation"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "legacy_attempts", id: :serial, force: :cascade do |t| create_table "legacy_attempts", id: :serial, force: :cascade do |t|
t.integer "recipient_id" t.integer "recipient_id"
t.integer "schedule_id" t.integer "schedule_id"
@ -399,6 +406,8 @@ ActiveRecord::Schema[7.0].define(version: 2022_10_15_023621) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "response_id" t.string "response_id"
t.bigint "gender_id"
t.index ["gender_id"], name: "index_students_on_gender_id"
t.index ["lasid"], name: "index_students_on_lasid" t.index ["lasid"], name: "index_students_on_lasid"
end end
@ -482,6 +491,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_10_15_023621) do
add_foreign_key "scores", "schools" add_foreign_key "scores", "schools"
add_foreign_key "student_races", "races" add_foreign_key "student_races", "races"
add_foreign_key "student_races", "students" add_foreign_key "student_races", "students"
add_foreign_key "students", "genders"
add_foreign_key "subcategories", "categories" add_foreign_key "subcategories", "categories"
add_foreign_key "survey_item_responses", "academic_years" add_foreign_key "survey_item_responses", "academic_years"
add_foreign_key "survey_item_responses", "schools" add_foreign_key "survey_item_responses", "schools"

@ -1,4 +1,9 @@
FactoryBot.define do FactoryBot.define do
factory :gender do
qualtrics_code { 1 }
designation { "MyString" }
end
factory :race_score do factory :race_score do
measure { nil } measure { nil }
school { nil } school { nil }

@ -1,9 +1,9 @@
Race Qualtrics Code,Race/Ethnicity,Gender Qualtrics Code,Sex/Gender Race Qualtrics Code,Race/Ethnicity,Gender Qualtrics Code,Sex/Gender
1,American Indian or Alaskan Native,1,Male 1,American Indian or Alaskan Native,2,Male
2,Asian or Pacific Islander,2,Female 2,Asian or Pacific Islander,1,Female
3,Black or African American,3,Another gender or gender identity not listed above 3,Black or African American,3,Another gender or gender identity not listed above
4,Hispanic or Latinx,4,Non-Binary 4,Hispanic or Latinx,4,Non-Binary
5,White or Caucasian,, 5,White or Caucasian,99,Unknown
6,Prefer not to disclose,, 6,Prefer not to disclose,,
7,Prefer to self-describe,, 7,Prefer to self-describe,,
8,Middle Eastern,, 8,Middle Eastern,,

1 Race Qualtrics Code Race/Ethnicity Gender Qualtrics Code Sex/Gender
2 1 American Indian or Alaskan Native 1 2 Male
3 2 Asian or Pacific Islander 2 1 Female
4 3 Black or African American 3 Another gender or gender identity not listed above
5 4 Hispanic or Latinx 4 Non-Binary
6 5 White or Caucasian 99 Unknown
7 6 Prefer not to disclose
8 7 Prefer to self-describe
9 8 Middle Eastern

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Gender, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -2,11 +2,17 @@ require 'rails_helper'
describe DemographicLoader do describe DemographicLoader do
let(:filepath) { 'spec/fixtures/sample_demographics.csv' } let(:filepath) { 'spec/fixtures/sample_demographics.csv' }
let(:codes) do let(:race_codes) do
{ 'American Indian or Alaskan Native' => 1, 'Asian or Pacific Islander' => 2, 'Black or African American' => 3, { 'American Indian or Alaskan Native' => 1, 'Asian or Pacific Islander' => 2, 'Black or African American' => 3,
'Hispanic or Latinx' => 4, 'White or Caucasian' => 5, 'Unknown' => 99, 'Middle Eastern' => 8, 'Multiracial' => 100 } 'Hispanic or Latinx' => 4, 'White or Caucasian' => 5, 'Unknown' => 99, 'Middle Eastern' => 8, 'Multiracial' => 100 }
end end
let(:gender_codes) do
{
'Female' => 1, 'Male' => 2, 'Another gender or gender identity not listed above' => 3, 'Non-Binary' => 4, 'Unknown' => 99
}
end
before :each do before :each do
DemographicLoader.load_data(filepath:) DemographicLoader.load_data(filepath:)
end end
@ -19,13 +25,25 @@ describe DemographicLoader do
it 'does not load qualtrics categories for `prefer not to disclose` or `prefer to self-describe`' do it 'does not load qualtrics categories for `prefer not to disclose` or `prefer to self-describe`' do
expect(Race.find_by_qualtrics_code(6)).to be nil expect(Race.find_by_qualtrics_code(6)).to be nil
end end
it 'loads all racial designations' do it 'loads all racial designations' do
expect(Race.all.count).to eq 8 expect(Race.all.count).to eq 8
codes.each do |key, value| race_codes.each do |key, value|
expect(Race.find_by_qualtrics_code(value)).not_to be nil expect(Race.find_by_qualtrics_code(value)).not_to eq nil
expect(Race.find_by_qualtrics_code(value).designation).to eq key expect(Race.find_by_qualtrics_code(value).designation).to eq key
expect(Race.find_by_designation(key)).not_to be nil expect(Race.find_by_designation(key)).not_to eq nil
expect(Race.find_by_designation(key).qualtrics_code).to be value expect(Race.find_by_designation(key).qualtrics_code).to eq value
end
end
it 'loads all gender designations' do
expect(Gender.all.count).to eq 5
gender_codes.each do |key, value|
expect(Gender.find_by_qualtrics_code(value)).not_to eq nil
expect(Gender.find_by_qualtrics_code(value).designation).to eq key
expect(Gender.find_by_designation(key)).not_to eq nil
expect(Gender.find_by_designation(key).qualtrics_code).to eq value
end end
end end
end end

@ -8,8 +8,13 @@ describe StudentLoader do
let(:latinx) { Race.find_by_qualtrics_code(4) } let(:latinx) { Race.find_by_qualtrics_code(4) }
let(:white) { Race.find_by_qualtrics_code(5) } let(:white) { Race.find_by_qualtrics_code(5) }
let(:middle_eastern) { Race.find_by_qualtrics_code(8) } let(:middle_eastern) { Race.find_by_qualtrics_code(8) }
let(:unknown) { Race.find_by_qualtrics_code(99) } let(:unknown_race) { Race.find_by_qualtrics_code(99) }
let(:multiracial) { Race.find_by_qualtrics_code(100) } let(:multiracial) { Race.find_by_qualtrics_code(100) }
let(:female) {Gender.find_by_qualtrics_code(1)}
let(:male) {Gender.find_by_qualtrics_code(2)}
let(:another_gender) {Gender.find_by_qualtrics_code(3)}
let(:non_binary) {Gender.find_by_qualtrics_code(4)}
let(:unknown_gender) {Gender.find_by_qualtrics_code(99)}
before :each do before :each do
Rails.application.load_seed Rails.application.load_seed
@ -22,9 +27,9 @@ describe StudentLoader do
context 'as a standalone function' do context 'as a standalone function' do
it 'race codes of 6 or 7 get classified as an unknown race' do it 'race codes of 6 or 7 get classified as an unknown race' do
codes = ['NA'] codes = ['NA']
expect(StudentLoader.process_races(codes:)).to eq [unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown_race]
codes = [] codes = []
expect(StudentLoader.process_races(codes:)).to eq [unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown_race]
codes = [1] codes = [1]
expect(StudentLoader.process_races(codes:)).to eq [american_indian] expect(StudentLoader.process_races(codes:)).to eq [american_indian]
codes = [2] codes = [2]
@ -38,11 +43,11 @@ describe StudentLoader do
codes = [8] codes = [8]
expect(StudentLoader.process_races(codes:)).to eq [middle_eastern] expect(StudentLoader.process_races(codes:)).to eq [middle_eastern]
codes = [6] codes = [6]
expect(StudentLoader.process_races(codes:)).to eq [unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown_race]
codes = [7] codes = [7]
expect(StudentLoader.process_races(codes:)).to eq [unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown_race]
codes = [6, 7] codes = [6, 7]
expect(StudentLoader.process_races(codes:)).to eq [unknown] expect(StudentLoader.process_races(codes:)).to eq [unknown_race]
codes = [1, 6, 7] codes = [1, 6, 7]
expect(StudentLoader.process_races(codes:)).to eq [american_indian] expect(StudentLoader.process_races(codes:)).to eq [american_indian]
codes = [1, 6, 7, 2] codes = [1, 6, 7, 2]
@ -57,8 +62,8 @@ describe StudentLoader do
describe '#add_multiracial_designation' do describe '#add_multiracial_designation' do
it 'adds the multiracial race code to the list of races' do it 'adds the multiracial race code to the list of races' do
races = [unknown] races = [unknown_race]
expect(StudentLoader.add_multiracial_designation(races:)).to eq [unknown] expect(StudentLoader.add_multiracial_designation(races:)).to eq [unknown_race]
races = [american_indian, asian] races = [american_indian, asian]
expect(StudentLoader.add_multiracial_designation(races:)).to eq [american_indian, asian, multiracial] expect(StudentLoader.add_multiracial_designation(races:)).to eq [american_indian, asian, multiracial]
races = [white] races = [white]
@ -106,13 +111,13 @@ end
def assigns_races_to_students 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_1').races).to eq [american_indian]
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_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_3').races).to eq [unknown_race]
expect(Student.find_by_response_id('student_survey_response_4').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_4').races).to eq [unknown_race]
expect(Student.find_by_response_id('student_survey_response_5').races).to eq [american_indian, asian, black, latinx, white, expect(Student.find_by_response_id('student_survey_response_5').races).to eq [american_indian, asian, black, latinx, white,
middle_eastern, multiracial] middle_eastern, multiracial]
expect(Student.find_by_response_id('student_survey_response_6').races).to eq [american_indian, asian, black, latinx, white, expect(Student.find_by_response_id('student_survey_response_6').races).to eq [american_indian, asian, black, latinx, white,
middle_eastern, multiracial] middle_eastern, multiracial]
expect(Student.find_by_response_id('student_survey_response_7').races).to eq [unknown] expect(Student.find_by_response_id('student_survey_response_7').races).to eq [unknown_race]
end end
def is_idempotent_for_students def is_idempotent_for_students

Loading…
Cancel
Save