← FC Coder · HomePhase 03 · Lesson 36 · 60 min
Lesson36
Phase Three · Fullstack · Matchday 36 · Link The Tables
多用户阵容
外键关联 + 用户隔离
Today's 3 Jobs · 今天这三件事
- 01squads 加 userId 外键 · push.references
- 02createSquad 注入 currentUser.id登录才能建
- 03🌟 /profile/[name] · 列该用户全部阵容.where userId
foreign key (`squads.userId.references(users.id)`) 把阵容和用户串起来。createSquad 注入 currentUser · /profile/[name] 用 .where 过滤。三抽屉关联 baby:players / squads / users 通过 id 串。下节课加 public/private。
Concept · 三抽屉关联
players + squads + users 通过 id 串
squads.userId ──refs──► users.id
FK
.references(() => users.id)
查
.where(eq(squads.userId, user.id))
好处
数据不重 · 一处改处处对
这是 1NF baby。Phase 5 进阶会讲 join / index / normalization。
Half 2 · 在屏幕上
FK · createSquad · /profile · AI 权限
01外键 + 旧数据处理
01Min
Cursor + pnpm dev
老三件套。
02Min
squads schema 加 userId: integer().notNull().references(() => users.id)
外键。
03Min
清空旧 squads(无 userId)· drizzle-kit push
如果有旧数据 · studio 清空 squads 表 · 再 push。否则 push 失败。
02action + profile 页
04Min
createSquad 内拿 getCurrentUser() · userId: user.id
auth.ts getCurrentUser · 注入。未登录 throw。
05Min
新建 app/profile/[name]/page.tsx · 列该用户全部阵容
查 user by name · 再查 squads where userId=user.id · 渲染链接列表。
03AI deleteSquad 权限
06Min
登 '哈兰德' · 创建 2 个阵容 · 访问 /profile/哈兰德
看 2 个 link。
07Min
隐身窗 登 '福登' · 创 1 个 · 访问 /profile/福登
看 1 个 link · 不看到哈兰德的(.where 过滤)。
08Min
AI Supervised:加 deleteSquad · 检查 squad.userId === currentUser.id 才删
Cmd+K · '加权限检查 · 别人不能删你的'。父亲必看(高风险)。
09Min
📸 截图两个 /profile 页
Phase 3 第十一张战利品。
讲给爸爸听
4 题 · 关联表
01foreign key 是什么?Hint ↓
一列的值必须存在另一表里。squad.userId 必须真有这个用户。
02数据库标准化 baby?Hint ↓
不要在两处存同一份数据。一处改 · 处处对。1NF baby。
03/profile/哈兰德 vs /profile/福登 不同?Hint ↓
.where(eq(squads.userId, user.id)) 过滤。
04本课为什么还不限制看别人?Hint ↓
public/private 是下节课。今天先关联。
温度计
给「串抽屉」打分
今天难度Difficulty
0
今天开心Fun
0
Final Whistle · 终场哨
抽屉串起来 —— 阵容知道是谁的。
还有 9 步没打勾。Step 7 两个 profile 看到各自的 = 算过。