第 6 部分 – 關聯
這個應用程式還有另一個功能 – 清單。如果您點擊提醒面板左側的按鈕,就會開啟一個側邊面板,顯示這個應用程式中不同的清單。
但現在,我們的控制台中只會看到一個錯誤,因為我們的應用程式預期會從 /api/lists
提取清單。讓我們模擬這個端點。
首先,我們將在伺服器頂部定義一個新的 list
模型
models: {
list: Model,
reminder: Model,
}
我們還會為 GET 到 /api/lists
的請求新增一個路由處理器,傳回所有清單
this.get("/api/lists", (schema, request) => {
return schema.lists.all()
})
Mirage 現在會回應 200,但沒有清單。讓我們在 seeds()
中建立一些清單
seeds(server) {
server.create("reminder", { text: "Walk the dog" });
server.create("reminder", { text: "Take out the trash" });
server.create("reminder", { text: "Work out" });
server.create("list", { name: "Home" });
server.create("list", { name: "Work" });
}
現在,當我們開啟側邊欄時,會看到兩個新的清單「家庭」和「工作」正在呈現。
嘗試點擊一個清單。您會看到一個錯誤,因為我們的應用程式預期存在另一個 API 端點:/api/lists/1/reminders
。這就是它擷取特定清單的提醒的方式。讓我們看看如何模擬它。
在 Mirage 中模擬處理關聯資料的端點最簡單的方式是使用關聯。我們會先使用 Mirage 的關聯輔助程式來為這個資料建模。
在這個應用程式中,清單和提醒之間存在一對多的關聯(一個清單可以有很多提醒),因此我們將使用 hasMany
和 belongsTo
輔助程式來定義這種關聯。
匯入這些輔助程式並更新您的模型以定義這種關聯
import { createServer, Model, hasMany, belongsTo } from "miragejs"
export default function () {
createServer({
models: {
list: Model.extend({
reminders: hasMany(),
}),
reminder: Model.extend({
list: belongsTo(),
}),
},
// rest of server
})
}
現在 Mirage 知道 list.reminders
和 reminder.list
屬性是關聯,因此我們可以開始在我們的路由處理器中使用它們。
讓我們使用我們新的關聯來模擬 /api/lists/:id/reminders
。這個端點應該查詢對應的清單,並回應屬於該清單的所有提醒。
以下是程式碼
this.get("/api/lists/:id/reminders", (schema, request) => {
let listId = request.params.id
let list = schema.lists.find(listId)
return list.reminders
})
我們使用 :id
的動態區段,它對應於我們點擊的清單。然後,我們使用該 ID 在 Mirage 的資料層中查詢對應的清單。最後,我們傳回與該清單關聯的提醒。
將此路由處理器複製到您的 Mirage 伺服器定義中,並嘗試點擊每個清單。您應該不會再看到錯誤。但是您也不會看到任何提醒。這是因為我們到目前為止建立的提醒並未與任何清單關聯 – 我們只是單獨建立它們。
若要為特定清單建立提醒,我們可以利用我們新的關聯。
seeds(server) {
// Unassociated reminders
server.create("reminder", { text: "Walk the dog" });
server.create("reminder", { text: "Take out the trash" });
server.create("reminder", { text: "Work out" });
let homeList = server.create("list", { name: "Home" });
server.create("reminder", { list: homeList, text: "Do taxes" });
let workList = server.create("list", { name: "Work" });
server.create("reminder", { list: workList, text: "Visit bank" });
}
現在,點擊「家庭」應該會顯示「繳稅」提醒。如果您點擊「全部」,應用程式將會連線至 /api/reminders
端點,它仍然會傳回我們系統中的所有提醒 – 包括與清單關聯的提醒,以及單獨存在的提醒。
最後,嘗試在 UI 中為特定清單建立新的提醒。點擊「工作」,然後新增「回覆 Jill」的提醒。如果您點擊應用程式,您會看到它已正確地與「工作」清單關聯。(它會顯示在「工作」和「全部」中,但不會顯示在「家庭」中)。
這是因為我們的 UI 已經在我們在清單上建立提醒時傳送 { listId }
。若要查看此情況,我們可以在我們現有的 POST 路由處理器中新增一個記錄,以檢查請求中的 attrs
this.post("/api/reminders", (schema, request) => {
let attrs = JSON.parse(request.requestBody)
console.log(attrs)
return schema.reminders.create(attrs)
})
當建立未關聯的待辦事項時,attrs 為 { text: "新待辦事項" }
,但關聯的待辦事項具有類似 { text: "回覆 Jill", listId: "2" }
的 attrs。
當我們定義關聯時,Mirage 在我們的模型上設定了特殊的屬性,稱為外來鍵。這就是它追蹤哪些模型彼此關聯的方式。設定類似 listId
或 reminderIds: []
的外來鍵足以更新關聯,並使其反映在您所有的 Mirage 路由處理器中。
因此,我們不必更新我們的 POST 處理器來適應我們 UI 的清單功能,因為 listId
已經傳遞到 reminders.create()
中。
Mirage 的關聯輔助程式足夠彈性,可以為幾乎任何資料情況建模,讓您在模擬處理關聯的端點時更容易完成工作。
重點
- Mirage 讓您可以定義和存取關聯資料
- 使用
belongsTo
和hasMany
輔助程式來定義模型上的具名關聯 - 在路由處理器中使用關聯來傳回與其他模型關聯的模型或集合
- Mirage 使用簡單的外來鍵來追蹤關聯資料