Files
juwan-backend/docs/ENT_EDGES_GUIDE.md
2026-02-28 05:33:16 +08:00

98 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ent Edges 使用说明(game 模块)
本文说明 `app/game/rpc/internal/models/schema` 下 Edges 的定义方式、生成方式,以及在业务代码中如何使用。
## 1. 当前 game 模块关系设计
基于 `desc/sql/game` 的表结构,当前主要关系:
- `players` 1:N `player_services`
- `player_services.player_id -> players.id`
- `shops` 1:N `shop_players`
- `shop_players.shop_id -> shops.id`
- `players` 1:N `shop_players`(逻辑关联)
- `shop_players.player_id -> players.id`
- `shops` 1:N `shop_invitations`
- `shop_invitations.shop_id -> shops.id`
- `players` 1:N `shop_invitations`(收到邀请)
- `shop_invitations.player_id -> players.id`
- `players` 1:N `shop_invitations`(发起邀请)
- `shop_invitations.invited_by -> players.id`
## 2. Edge 定义规则
### 2.1 在子表(持有外键字段)上定义 `edge.From(...).Field(...)`
示例(`player_services`):
- `edge.From("player", Players.Type).Ref("services").Field("player_id").Required().Unique()`
含义:
- 当前实体(`player_services`)通过 `player_id` 指向一个 `players`
- `Unique()` 表示每条 `player_services` 记录只对应一个 player(典型 N:1 子侧定义)
### 2.2 在父表定义反向 `edge.To(...)`
示例(`players`):
- `edge.To("services", PlayerServices.Type)`
含义:
- 一个 player 可以有多条 service1:N
## 3. 代码生成
在项目根目录执行:
```bash
go run entgo.io/ent/cmd/ent generate ./app/game/rpc/internal/models/schema
```
如果你后续为 schema 增加了注解或字段,重复执行同一命令即可刷新生成代码。
## 4. 业务查询示例
> 以下为典型写法,具体包路径以你项目实际生成结果为准。
### 4.1 查询某个玩家及其所有服务
```go
player, err := client.Players.
Query().
Where(players.ID(playerID)).
WithServices().
Only(ctx)
```
### 4.2 查询某个店铺及其成员关系记录
```go
shop, err := client.Shops.
Query().
Where(shops.ID(shopID)).
WithMemberships().
Only(ctx)
```
### 4.3 查询某玩家收到的邀请
```go
invitations, err := client.Players.
QueryReceivedInvitations(player).
All(ctx)
```
## 5. 常见坑
- `edge.From(...).Field(...)` 的字段名必须是当前 schema 里真实存在的字段。
- `Ref("...")` 名称要和对端 `edge.To("...")` 保持一致。
- 同一实体指向同一目标实体的多条边(例如邀请的 `player``inviter`)必须使用不同 edge 名称,避免代码生成冲突。
- 如果 SQL 没有声明外键但你定义了带 `Field(...)` 的 edge,迁移时可能会生成外键约束;若不想生成,请保持和 SQL 一致或在迁移层显式控制。
## 6. 当前文件位置
- Schema 目录:`app/game/rpc/internal/models/schema`
- SQL 来源:`desc/sql/game`