Core Concepts
Advanced Relations
Many-to-many, polymorphic, one-to-one, and nested relations with configurable cascade actions.
Advanced Relations
FastCMS supports advanced relationship types with configurable cascade actions.
Status: Schema validation works for all relation types. Runtime enforcement of many-to-many, polymorphic, and cascade actions is pending.
Relation Types
| Type | Description |
|---|---|
many-to-one | Multiple records reference one parent (default) |
one-to-many | One record can have many related records |
many-to-many | Records relate to multiple records in both directions |
one-to-one | Each record relates to exactly one other |
polymorphic | Relate to records from multiple collections |
Cascade Actions
| Action | Behavior |
|---|---|
restrict | Prevent deletion if related records exist (default) |
cascade | Delete related records automatically |
set_null | Set foreign key to NULL when parent is deleted |
no_action | Standard SQL — may leave orphaned records |
Relation Schema Options
{
"name": "author",
"type": "relation",
"relation": {
"collection_id": "users",
"type": "many-to-one",
"cascade_delete": "restrict",
"display_fields": ["name", "email"],
"max_depth": 2
}
}| Field | Description | Default |
|---|---|---|
collection_id | Target collection ID | Required |
collection_ids | Target collection IDs (for polymorphic) | null |
type | Relationship type | one-to-many |
cascade_delete | Action on parent deletion | restrict |
display_fields | Fields to show in relation | ["id"] |
max_depth | Nested loading depth (0–5) | 1 |
junction_table | Junction table for many-to-many | null |
junction_field | Field referencing this collection | null |
target_field | Field referencing target collection | null |
Examples
Many-to-One (Posts → Author)
{
"name": "author",
"type": "relation",
"relation": {
"collection_id": "users",
"type": "many-to-one",
"cascade_delete": "set_null",
"display_fields": ["name", "email"]
}
}One-to-Many (Post → Comments)
{
"name": "post",
"type": "relation",
"relation": {
"collection_id": "posts",
"type": "one-to-many",
"cascade_delete": "cascade",
"display_fields": ["title"]
}
}Many-to-Many (Posts ↔ Tags)
{
"name": "tags",
"type": "relation",
"relation": {
"collection_id": "tags",
"type": "many-to-many",
"junction_table": "posts_tags",
"junction_field": "post_id",
"target_field": "tag_id",
"display_fields": ["name"]
}
}Polymorphic (Comments on Posts or Events)
{
"name": "commentable",
"type": "relation",
"relation": {
"collection_ids": ["posts", "events"],
"type": "polymorphic",
"polymorphic_type_field": "commentable_type",
"display_fields": ["title"]
}
}Choosing Cascade Actions
// Comments should be deleted with their post
{"cascade_delete": "cascade"}
// Posts should persist when author is deleted
{"cascade_delete": "set_null"}
// Can't delete if dependencies exist
{"cascade_delete": "restrict"}Current Limitations
| Feature | Status |
|---|---|
| Schema validation | ✅ |
| Basic one-to-many expansion | ✅ |
| Automatic junction tables | ⏳ Pending |
| Polymorphic querying | ⏳ Pending |
| Recursive loading (depth > 1) | ⏳ Pending |
| Cascade action enforcement | ⏳ Pending |