---
tags: Node.js 直播班 - 2022 春季班
---
# 🏅 Day 39
## 追蹤 / 取消追蹤使用者功能
**執行流程:**
A 使用者對其他使用者(如 B) 點擊追蹤時,會分別在 A 使用者的 user 資料 followings 欄位加入 B 的 ID,B 使用者的 user 資料 followers 欄位也會加入 A 的 ID
若執行取消追蹤則從 A 使用者的 user 資料 followings 欄位、B 使用者的 user 資料 followers 欄位移除 ID
**實作前準備**
需先於 user Model 中加入 followers 與 follwing 欄位,預計會加入使用者 ID 及加入時間([參考](https://github.com/gonsakon/express-week4-sample/blob/week8/models/usersModel.js#L29-L46))
`由於社群網站在設計上會限制 500 位會員數,預計在兩個欄位中分別加入 499 個 user ID 不會超過 MongoDB Document 的 16mb 容量限制,因此可使用直接將 ID 加入 user 資料的方式執行`
```javascript
followers: [
{
user: { type: mongoose.Schema.ObjectId, ref: 'User' },
createdAt: {
type: Date,
default: Date.now
}
}
],
following: [
{
user: { type: mongoose.Schema.ObjectId, ref: 'User' },
createdAt: {
type: Date,
default: Date.now
}
}
]
```
### 題目(將答案寫在 HackMD 並提交至回報區)
**實作使用者追蹤、取消追蹤功能**
可參考第八週[範例程式碼](https://github.com/gonsakon/express-week4-sample)
- 設計追蹤路由 POST`users/:id/follow`、取消追蹤路由 DELETE `users/:id/unfollow`
- 需登入通過 JWT 驗證才能請求
- 不能追蹤或取消追蹤帳號本人
- 追蹤與取消追蹤都需調整追蹤者與被追蹤者雙方的 user 資料
- 使用 updateOne() 搭配 `$addToSet` `$pull` 將使用者 ID 加入或移除
- 準備好兩個已註冊過的帳號,測試可以正確互相追蹤以及取消追蹤
回報流程
---
請同學依照下圖教學觀看解答、回報答案:

回報格式:請在「回報區」貼上 CodePen 或 HackMD 連結回報答案 (為了統計人數,請同學依序加上「報數」)
<!-- 解答
models/usersModel.js
https://github.com/gonsakon/express-week4-sample/blob/week8/models/usersModel.js#L29-L46
routes/users.js
參考 https://github.com/gonsakon/express-week4-sample/blob/week8/routes/users.js#L90-L144
```javascript
router.post('/:id/follow',isAuth, handleErrorAsync(async(req, res, next) =>{
if (req.params.id === req.user.id) {
return next(appError(401,'您無法追蹤自己',next));
}
await User.updateOne(
{
_id: req.user.id,
'following.user': { $ne: req.params.id }
},
{
$addToSet: { following: { user: req.params.id } }
}
);
await User.updateOne(
{
_id: req.params.id,
'followers.user': { $ne: req.user.id }
},
{
$addToSet: { followers: { user: req.user.id } }
}
);
res.status(200).json({
status: 'success',
message: '您已成功追蹤!'
});
}))
router.delete('/:id/unfollow',isAuth, handleErrorAsync(async(req, res, next) =>{
if (req.params.id === req.user.id) {
return next(appError(401,'您無法取消追蹤自己',next));
}
await User.updateOne(
{
_id: req.user.id
},
{
$pull: { following: { user: req.params.id } }
}
);
await User.updateOne(
{
_id: req.params.id
},
{
$pull: { followers: { user: req.user.id } }
}
);
res.status(200).json({
status: 'success',
message: '您已成功取消追蹤!'
});
}))
```
-->
回報區
---
| 報數 | 組別 / 名字 | codepen / hackMD / 其他回饋 |
| ---- | ----------- | ------------------ |
|1| 第 3 組 / Hobby | [HackMD](https://hackmd.io/@hobbyling/day39) |
|2| 第 5 組 @ Hazel | [HackMD@Hazel](https://hackmd.io/@hazelwu/day39) |
|3| 第 4 組 / 苡安 | [HackMD](https://hackmd.io/f-tmyR1ZQvqsni1glhyz8A) |
|3| 第 14 組|East | [HackMD](https://hackmd.io/TQGzSJ0cSMaTOBDxd9GPIw) |
|4| 第 11 組|Han Lai | [HackMD](https://hackmd.io/3v8lZ4oZSUGqLS4Gm6QVOA?view) |
|5| 第 16 組|皓皓 | [HackMD](https://hackmd.io/@cutecat8110/rJdddlVs5) |