From e90e6a4f0f26e20758e3d9af3b313d7c33d9153a Mon Sep 17 00:00:00 2001 From: rebuilt Date: Mon, 21 Apr 2025 16:21:38 -0700 Subject: [PATCH] WIP: add multiple languages to parent --- app/models/parent.rb | 3 ++- app/models/parent_language.rb | 4 +++ app/models/survey_item_response.rb | 8 ++++-- app/services/survey_item_values.rb | 25 +++++++++++++++++ app/services/survey_responses_data_loader.rb | 8 +++++- .../20250418184427_create_parent_languages.rb | 12 +++++++++ ...85032_add_designation_index_to_language.rb | 5 ++++ ...50418185655_remove_language_from_parent.rb | 5 ++++ db/schema.rb | 27 +++++++++++++++---- spec/factories.rb | 13 +++++++++ spec/models/parent_language_spec.rb | 5 ++++ spec/services/survey_item_values_spec.rb | 20 ++++++++++++-- .../survey_responses_data_loader_spec.rb | 9 +++++++ 13 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 app/models/parent_language.rb create mode 100644 db/migrate/20250418184427_create_parent_languages.rb create mode 100644 db/migrate/20250418185032_add_designation_index_to_language.rb create mode 100644 db/migrate/20250418185655_remove_language_from_parent.rb create mode 100644 spec/models/parent_language_spec.rb diff --git a/app/models/parent.rb b/app/models/parent.rb index 7486bf7f..ea815ac8 100644 --- a/app/models/parent.rb +++ b/app/models/parent.rb @@ -1,4 +1,5 @@ class Parent < ApplicationRecord - belongs_to :language, optional: true belongs_to :housing, optional: true + has_many :parent_languages + has_and_belongs_to_many :languages, join_table: :parent_languages end diff --git a/app/models/parent_language.rb b/app/models/parent_language.rb new file mode 100644 index 00000000..ec878727 --- /dev/null +++ b/app/models/parent_language.rb @@ -0,0 +1,4 @@ +class ParentLanguage < ApplicationRecord + belongs_to :parent + belongs_to :language +end diff --git a/app/models/survey_item_response.rb b/app/models/survey_item_response.rb index d89eee5b..f04e22d0 100644 --- a/app/models/survey_item_response.rb +++ b/app/models/survey_item_response.rb @@ -52,8 +52,12 @@ class SurveyItemResponse < ActiveRecord::Base } scope :averages_for_language, lambda { |survey_items, school, academic_year, language| - SurveyItemResponse.where(survey_item: survey_items, school:, - academic_year:, language:, grade: school.grades(academic_year:)).group(:survey_item).having("count(*) >= 10").average(:likert_score) + # SurveyItemResponse.where(survey_item: survey_items, school:, + # academic_year:, language:, grade: school.grades(academic_year:)).group(:survey_item).having("count(*) >= 10").average(:likert_score) + # + # + # Parent.joins(:languages).where(languages: {designation: "Spanish"}) + # SurveyItemResponse.joins([parent: :languages]).where(languages: {designation: "English"}).first } def self.grouped_responses(school:, academic_year:) @grouped_responses ||= Hash.new do |memo, (school, academic_year)| diff --git a/app/services/survey_item_values.rb b/app/services/survey_item_values.rb index 779da43e..be4833bc 100644 --- a/app/services/survey_item_values.rb +++ b/app/services/survey_item_values.rb @@ -20,6 +20,9 @@ class SurveyItemValues row["Progress Count"] = progress row["Race"] ||= races.join(",") row["Gender"] ||= gender + row["Raw Housing Status"] = raw_housing + row["Housing Status"] = housing + row["Home Languages"] = languages.join(",") copy_data_to_main_column(main: /Race/i, secondary: /Race Secondary|Race-1/i) copy_data_to_main_column(main: /Gender/i, secondary: /Gender Secondary|Gender-1/i) @@ -195,6 +198,28 @@ class SurveyItemValues @sped ||= Sped.to_designation(raw_sped) end + def raw_housing + @raw_housing ||= value_from(pattern: /Housing/i) + end + + def housing + @housing ||= Housing.to_designation(raw_housing) + end + + def raw_language + @raw_language ||= value_from(pattern: /^Language$/i) + end + + def languages + @languages ||= [].tap do |languages| + if raw_language.present? + raw_language.split(",").each do |item| + languages << Language.to_designation(item) + end + end + end + end + def number_of_children @number_of_children ||= value_from(pattern: /Number\s*Of\s*Children/i).to_i end diff --git a/app/services/survey_responses_data_loader.rb b/app/services/survey_responses_data_loader.rb index 340e8bf9..9c653aaf 100644 --- a/app/services/survey_responses_data_loader.rb +++ b/app/services/survey_responses_data_loader.rb @@ -95,6 +95,10 @@ class SurveyResponsesDataLoader process_survey_items(row:) end + def languages + @languages ||= Language.by_designation + end + def process_survey_items(row:) student = nil parent = nil @@ -108,7 +112,9 @@ class SurveyResponsesDataLoader if row.respondent_type == :parent parent = Parent.find_or_create_by(response_id: row.response_id) parent.number_of_children = row.number_of_children - parent.language = row.language + tmp_languages = row.languages.map { |language| languages[language] } + parent.languages.concat(tmp_languages) + parent.housing = Housing.find_by(designation: row.housing) parent.save end diff --git a/db/migrate/20250418184427_create_parent_languages.rb b/db/migrate/20250418184427_create_parent_languages.rb new file mode 100644 index 00000000..1cae5fc1 --- /dev/null +++ b/db/migrate/20250418184427_create_parent_languages.rb @@ -0,0 +1,12 @@ +class CreateParentLanguages < ActiveRecord::Migration[8.0] + def change + create_table :parent_languages do |t| + t.references :parent, null: false, foreign_key: true + t.references :language, null: false, foreign_key: true + + t.timestamps + end + + add_index :parent_languages, %i[parent_id language_id] + end +end diff --git a/db/migrate/20250418185032_add_designation_index_to_language.rb b/db/migrate/20250418185032_add_designation_index_to_language.rb new file mode 100644 index 00000000..221b98bf --- /dev/null +++ b/db/migrate/20250418185032_add_designation_index_to_language.rb @@ -0,0 +1,5 @@ +class AddDesignationIndexToLanguage < ActiveRecord::Migration[8.0] + def change + add_index :languages, %i[designation] + end +end diff --git a/db/migrate/20250418185655_remove_language_from_parent.rb b/db/migrate/20250418185655_remove_language_from_parent.rb new file mode 100644 index 00000000..948e030d --- /dev/null +++ b/db/migrate/20250418185655_remove_language_from_parent.rb @@ -0,0 +1,5 @@ +class RemoveLanguageFromParent < ActiveRecord::Migration[8.0] + def change + remove_column :parents, :language_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 4c533464..84afd42a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_04_15_211114) do +ActiveRecord::Schema[8.0].define(version: 2025_04_18_185655) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" enable_extension "pg_stat_statements" @@ -97,6 +97,14 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_15_211114) do t.index ["slug"], name: "index_incomes_on_slug", unique: true end + create_table "languages", force: :cascade do |t| + t.string "designation" + t.string "slug" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["designation"], name: "index_languages_on_designation" + end + create_table "legacy_attempts", id: :serial, force: :cascade do |t| t.integer "recipient_id" t.integer "schedule_id" @@ -317,15 +325,23 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_15_211114) do t.index ["subcategory_id"], name: "index_measures_on_subcategory_id" end + create_table "parent_languages", force: :cascade do |t| + t.bigint "parent_id", null: false + t.bigint "language_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["language_id"], name: "index_parent_languages_on_language_id" + t.index ["parent_id", "language_id"], name: "index_parent_languages_on_parent_id_and_language_id" + t.index ["parent_id"], name: "index_parent_languages_on_parent_id" + end + create_table "parents", force: :cascade do |t| t.string "response_id" t.integer "number_of_children" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.bigint "housing_id", null: false - t.bigint "language_id" + t.bigint "housing_id" t.index ["housing_id"], name: "index_parents_on_housing_id" - t.index ["language_id"], name: "index_parents_on_language_id" end create_table "races", force: :cascade do |t| @@ -514,8 +530,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_04_15_211114) do 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 "measures", "subcategories" + add_foreign_key "parent_languages", "languages" + add_foreign_key "parent_languages", "parents" add_foreign_key "parents", "housings" - add_foreign_key "parents", "languages" add_foreign_key "respondents", "academic_years" add_foreign_key "respondents", "schools" add_foreign_key "response_rates", "academic_years" diff --git a/spec/factories.rb b/spec/factories.rb index cb4b22c6..7f5ee504 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,4 +1,17 @@ FactoryBot.define do + factory :parent_language do + parent { nil } + language { nil } + end + + factory :language do + designation { "MyString" } + end + + factory :housing do + designation { "MyString" } + end + factory :parent do response_id { "MyString" } number_of_children { 1 } diff --git a/spec/models/parent_language_spec.rb b/spec/models/parent_language_spec.rb new file mode 100644 index 00000000..720c6862 --- /dev/null +++ b/spec/models/parent_language_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ParentLanguage, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/services/survey_item_values_spec.rb b/spec/services/survey_item_values_spec.rb index e884d645..ac60e8c3 100644 --- a/spec/services/survey_item_values_spec.rb +++ b/spec/services/survey_item_values_spec.rb @@ -414,7 +414,7 @@ RSpec.describe SurveyItemValues, type: :model do end context "when there are multiple races" do - it "returns the gender that maps to the gender provided" do + it "returns the race that maps to the race provided" do row = { "Race" => "1,2,3" } values = SurveyItemValues.new(row:, headers:, survey_items:, schools:, academic_years:) expect(values.races).to eq [1, 2, 3, 100] @@ -452,7 +452,7 @@ RSpec.describe SurveyItemValues, type: :model do headers.push("HispanicLatino") headers.push("Race- SIS") values = SurveyItemValues.new(row:, headers:, survey_items:, schools:, academic_years:) - expect(values.races).to eq [5, 2, 3, 4, 100] + expect(values.races).to eq [2, 3, 4, 100] end end end @@ -567,6 +567,22 @@ RSpec.describe SurveyItemValues, type: :model do # end end + context ".language" do + before :each do + attleboro + ay_2022_23 + end + + it "validates the code matches the expectations defined in the demographic_glossary" do + + list = read(demographic_filepath, "Language Value", "Language Type") + + list.each do |target, result| + compare("Language", target, [result], :languages) + end + end + end + context ".ell" do before :each do attleboro diff --git a/spec/services/survey_responses_data_loader_spec.rb b/spec/services/survey_responses_data_loader_spec.rb index 2f2cf747..8baba8a0 100644 --- a/spec/services/survey_responses_data_loader_spec.rb +++ b/spec/services/survey_responses_data_loader_spec.rb @@ -123,6 +123,13 @@ describe SurveyResponsesDataLoader do let(:unknown_race) { create(:race, qualtrics_code: 99) } let(:multiracial) { create(:race, qualtrics_code: 100) } + let(:languages){ + create(:language, designation: "English") + create(:language, designation: "Spanish") + create(:language, designation: "Portuguese") + create(:language, designation: "Unknown") + } + let(:setup) do ay_2020_21 ay_2022_23 @@ -161,6 +168,8 @@ describe SurveyResponsesDataLoader do middle_eastern unknown_race multiracial + + languages end before :each do