A relationship connects two tables with a foreign key. When you add a relationship field, Archie creates the foreign key in the database, generates the inverse field on the other table automatically, and exposes both sides as nested fields in the GraphQL API. This page covers the cardinalities you can model, how to set up many-to-many, and how the relationships look in the auto-generated APIs.Documentation Index
Fetch the complete documentation index at: https://archie.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Cardinality
| Cardinality | What it means | Real-world example |
|---|---|---|
| One-to-One | Record A ↔ exactly one Record B (and vice versa). | A User has one Profile. |
| One-to-Many | Record A ↔ many Record Bs, but each B belongs to exactly one A. | An Author has many Books; each Book has one Author. |
| Many-to-Many | Record A ↔ many Record Bs and Record B ↔ many Record As. | A Student takes many Courses; a Course has many Students. |
One-to-many
The most common cardinality. The “many” side holds the foreign key. Example: anauthor has many books. The books table holds an author_id relationship field pointing to authors.
When you add the author relationship on books with cardinality One-to-Many (one author, many books), Archie automatically:
- Creates the
author_idforeign key column onbooks. - Generates a
booksnested field onAuthorin the GraphQL schema. - Generates an
authornested field onBookin the GraphQL schema.
One-to-one
Auser has exactly one profile, and a profile belongs to exactly one user.
Add a relationship field on the side that owns the foreign key (typically profile.user_id), pick One-to-One as the cardinality, and Archie enforces the uniqueness so that no two profiles can point to the same user.
Many-to-many
For many-to-many, create a join table that holds two relationship fields — one to each side. Example: students enrolling in courses.- Create a
studentstable. - Create a
coursestable. - Create a
student_coursesjoin table with two fields:student— relationship tostudents, cardinality One-to-Many.course— relationship tocourses, cardinality One-to-Many.
- Optionally, add a unique index across
(student, course)to prevent duplicate enrollments.
enrolled_at, grade) to record per-link metadata.
Mandatory vs. optional relationships
Toggle Mandatory on the relationship field to require a related record. A non-mandatory relationship can benull — for example, a comment can optionally belong to a parent_comment for threaded replies.
Cascade behavior on delete
By default, the database prevents you from deleting a record that other records reference — this protects against orphaned data. If you have anauthor with books, deleting the author fails until the books are reassigned or deleted.
Common alternatives:
| Behavior | What it does | When to use it |
|---|---|---|
| Restrict (default) | Block the delete while related records exist. | Default. Forces you to handle related data explicitly. |
| Cascade | Delete related records too. | Strong ownership — deleting a post should delete its comments. |
| Set null | Clear the reference; keep the related records. | Loose ownership — deleting a category shouldn’t delete its posts, just unlink them. |
How it appears in the API
Every relationship is exposed in the auto-generated GraphQL API as a nested field on each side. Filtering, sorting, and pagination on related collections is supported. See the GraphQL API Explorer to inspect the exact shape generated for your tables. The REST API exposes related records via standard endpoint patterns and query parameters.Permissions
Reading or writing a relationship requires permissions on both sides. A user can only see related records on a table they’re allowed to read. Configure this in Role-Based Access.FAQ
Why is there no Many-to-Many option in the relationship field?
Why is there no Many-to-Many option in the relationship field?
Many-to-many is always implemented under the hood as a join table with two one-to-many relationships. Modeling it explicitly gives you a place to attach metadata to each link (for example, when a student enrolled, what grade they got). The Data Model exposes that pattern directly rather than hiding it.
Do I need to manually add a foreign key column?
Do I need to manually add a foreign key column?
No. The relationship field is the foreign key. Adding it creates the column, the database constraint, and the inverse query in GraphQL all at once.
What happens to the inverse if I rename a relationship field?
What happens to the inverse if I rename a relationship field?
The inverse field updates to match the new name. Any client code that referenced the old nested field name needs to be updated.
Can I have multiple relationships between the same two tables?
Can I have multiple relationships between the same two tables?
Yes. For example, a
messages table could have both a sender and a recipient relationship pointing to users. Pick distinct field names so the two relationships are clearly distinguishable in the GraphQL schema.What does cascade delete look like in practice?
What does cascade delete look like in practice?
When you delete a
post with comments configured to cascade, the database deletes the post and every comment that points to it as part of the same transaction. Choose cascade only when child records have no meaning without the parent.