alumni_lookup

Education Model Foundation (Phase 18.2)

Summary

Phase 18.2 introduces the new education data foundation used by the migration from the legacy Degree -> Major -> College chain to Education -> EducationAreaOfStudy.

This is a backend/schema release only. No user-facing read paths were migrated in 18.2.

What Was Added

Tables

Models

Alumni Associations

Data Integrity

Database constraints

Derived fields

Compatibility Notes

Migrations

Test Coverage

Model tests added:

Coverage includes:


Phase 18.8 — Per-Enrollment Student Data

New Columns on educations

Education.in_progress Scope

The canonical single source of truth for current enrollment:

scope :in_progress, -> {
  where(date_issued: nil)
    .where("educations.student_status IS NULL OR educations.student_status = 'pending'")
}

The column is table-qualified (educations.student_status) to avoid PG::AmbiguousColumn when joined to alumni, which also has student_status. Never use where(student_status: ...) in a scope that may be composed with an alumni join.

Education::ENROLLMENT_COLLEGE_CODE_SQL

Canonical COALESCE SQL constant resolving an in-progress row’s college code:

ENROLLMENT_COLLEGE_CODE_SQL = <<~SQL.squish
  COALESCE(
    NULLIF(NULLIF(educations.current_school_code, ''), '00'),
    educations.granting_school_code
  )
SQL

Use this constant anywhere a query needs the “effective college” for an in-progress education row.

Alumni Enrollment Delegation

All Alumni enrollment methods now delegate to Education.in_progress rather than reading alumni.current_school_code and siblings:

# Scopes
scope :currently_enrolled, -> { joins(:educations).merge(Education.in_progress).distinct }
scope :current_students,   -> { currently_enrolled.where.not(buid: Education::AggregateScope.buid_subquery) }

# Instance methods
def currently_enrolled? = educations.merge(Education.in_progress).exists?
alias current_student? currently_enrolled?
def current_enrollment_education = educations.merge(Education.in_progress).order(created_at: :desc).first

Csv::EducationImporter Phase 18.8 Additions

Two new private methods called after each education save:

New Migrations

Migration Purpose
20260528191923_add_honorary_degree_college Seeds the honorary-degree college row so education.college always resolves
20260528221509_add_current_student_fields_to_educations Adds expected_graduation_year (integer) + student_status (string) with indexes

Deferrals (Phase 18.8 Deploy 2)

The following are intentionally deferred to a second deploy to allow safe rollout:

What Was Retired