Content Types
关联关系
6 种关联类型,自动创建中间表,查询时自动填充。
关联关系将内容类型连接在一起。通过 field_type = "relation" 和 relation 配置来定义。
关联类型
| 类型 | 描述 | 外键位置 | 数据格式 |
|---|---|---|---|
one_to_one | 单条关联记录 | 源表 | 字符串(目标 ID) |
one_to_many | 目标表中的多条记录 | 目标表 | ID 数组 |
many_to_one | 属于 | 源表 | 字符串(目标 ID) |
many_to_many | 通过中间表 | 中间表 | ID 数组 |
one_way | 单向引用 | 源表 | 字符串(目标 ID) |
many_way | 单向多对多 | 中间表 | ID 数组 |
Many To One(多对一)
最常见的关联 — "属于"。外键在源表中。
# 每门课程属于一个讲师
[[fields]]
name = "instructor"
field_type = "relation"
relation = { relation_type = "many_to_one", target = "instructors" }系统会在 courses 表中添加 instructor_id 列。
# 创建课程并关联讲师
curl -X POST http://localhost:9898/api/v1/cms/courses \
-d '{"title":"Rust 入门","instructor":"<instructor_id>"}'One To Many(一对多)
"many_to_one 的反向"。外键在目标表中。
# 讲师有很多课程(外键在 courses 表中)
[[fields]]
name = "courses"
field_type = "relation"
relation = { relation_type = "one_to_many", target = "courses" }这不会添加新列 — 它读取目标侧已有的外键。用于反向查询。
Many To Many(多对多)
通过自动创建的中间表关联。
# 课程有多个标签
[[fields]]
name = "tags"
field_type = "relation"
relation = { relation_type = "many_to_many", target = "tags", through = "courses_tags" }系统自动创建 courses_tags 中间表,包含 course_id 和 tag_id 列。使用 INSERT IGNORE 防止重复。
# 创建带标签的课程
curl -X POST http://localhost:9898/api/v1/cms/courses \
-d '{"title":"Rust 入门","tags":["<tag_id_1>","<tag_id_2>"]}'One To One(一对一)
单条关联记录 — 外键在源表中。
# 每个用户有一个档案
[[fields]]
name = "profile"
field_type = "relation"
relation = { relation_type = "one_to_one", target = "profiles" }One Way(单向引用)
单向引用 — 类似 many_to_one,但目标侧不会创建反向关联。
# 书签引用文章,但文章不知道有哪些书签
[[fields]]
name = "article_ref"
field_type = "relation"
relation = { relation_type = "one_way", target = "articles" }Many Way(单向多对多)
通过中间表的单向多关联 — 目标侧无反向引用。
[[fields]]
name = "recommended"
field_type = "relation"
relation = { relation_type = "many_way", target = "courses", through = "course_recommendations" }关联配置选项
[[fields]]
name = "author"
field_type = "relation"
relation = { relation_type = "many_to_one", target = "users", foreign_key = "author_id" }
required = true| 选项 | 必填 | 默认值 | 说明 |
|---|---|---|---|
relation_type | 是 | — | 6 种类型之一 |
target | 是 | — | 目标表名 |
foreign_key | 否 | {field_name}_id | 自定义外键列名 |
through | 否 | {source}_{target} | 中间表名(M2M / ManyWay) |
此外,required = true 会使外键列为 NOT NULL。
用 include 填充关联
默认情况下,关联字段返回 ID。使用 include 参数将它们展开为完整记录:
# 填充单个关联
curl http://localhost:9898/api/v1/cms/courses?include=instructor
# 填充多个关联
curl http://localhost:9898/api/v1/cms/courses?include=instructor,tags
# 嵌套填充 — 课程中填充课时
curl http://localhost:9898/api/v1/cms/courses?include=instructor,lessons,tags使用 include 的响应:
{
"id": "abc123",
"title": "Rust 入门",
"instructor": {
"id": "xyz789",
"name": "Alice"
},
"tags": [
{ "id": "t1", "name": "Rust" },
{ "id": "t2", "name": "编程" }
]
}不带 include 时,同一请求返回:
{
"id": "abc123",
"title": "Rust 入门",
"instructor": "xyz789",
"tags": ["t1", "t2"]
}按关联过滤
使用 {field_name}_id 按关联过滤:
# 查询某讲师的所有课程
curl "http://localhost:9898/api/v1/cms/courses?instructor_id=xyz789"
# 查询某课程的所有课时
curl "http://localhost:9898/api/v1/cms/lessons?course_id=abc123"中间表自动清理
删除记录时,ManyToMany / ManyWay 的中间表行会自动移除,不会产生孤立引用。
最佳实践
- 双向定义关联 — 例如 Course → Instructor 用
many_to_one,Instructor → Courses 用one_to_many。这样才能双向include。 - 让系统自动命名中间表 — 除非需要特定名称,否则省略
through;默认的{source}_{target}命名约定清晰一致。 - 使用
one_way/many_way— 当目标内容类型不需要反向链接时(如活动日志、审计引用)。
