Skip to content

Relationships: many-to-many via an auto-managed junction table #13

Description

@jkalias

Sub-issue of #3. Builds on the FK plumbing from the many-to-one / one-to-many sub-issue; the most involved increment.

Scope

Support many-to-many (e.g. StudentCourse), where neither side holds a scalar FK and the association lives in a separate junction table the library creates and maintains.

Design

  • Declaration. A macro on each side (or one declaration generating both directions), e.g. MEMBER_COLLECTION(Course, courses) on Student and MEMBER_COLLECTION(Student, students) on Course. These are not columns on either table; they declare a link to be backed by a junction table.
  • Junction table. The library auto-creates and names a link table — e.g. Student_Course with columns student_id INTEGER REFERENCES Student(id), course_id INTEGER REFERENCES Course(id), a composite PRIMARY KEY(student_id, course_id), and ON DELETE CASCADE so removing either endpoint cleans up links. Naming must be deterministic and collision-resistant (define ordering of the two record names). This is registered/created alongside user tables in Database::Database, respecting the same dependency ordering from the many-to-one sub-issue.
  • Mutation API. Junction rows are managed by the library, not the user: db.Link(student, course) / db.Unlink(student, course) (insert/delete a junction row), idempotent on the composite key.
  • Fetching. db.FetchRelated<Course>(&Student::courses, student) joins through the junction table to return the related records; the inverse works symmetrically.
  • Integrity on delete. Deleting a Student or Course must remove its junction rows (ON DELETE CASCADE); add a test that a deleted endpoint leaves no orphaned links.

Acceptance criteria

  • Declaring a many-to-many on both sides auto-creates a correctly named junction table with composite PK and cascading FKs.
  • Link/Unlink add/remove associations idempotently; FetchRelated returns the correct set in both directions.
  • Deleting an endpoint removes its junction rows, leaving no orphans (test included).
  • README "Relationships" section extended with the many-to-many form and the junction-table naming rule.

Out of scope

Association attributes (extra columns on the junction row beyond the two FKs) — track separately if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions