模型代表一組結構化的資料,稱為記錄 (records)。模型通常對應到資料庫中的表格/集合 (table/collection),屬性 (attributes) 對應到欄位/欄 (columns/fields),而記錄對應到列/文件 (rows/documents)。
依照慣例,模型是透過在 Sails 應用程式的 api/models/
資料夾中建立檔案來定義
// api/models/Product.js
module.exports = {
attributes: {
nameOnMenu: { type: 'string', required: true },
price: { type: 'string', required: true },
percentRealMeat: { type: 'number', defaultsTo: 20, columnType: 'FLOAT' },
numCalories: { type: 'number' },
},
};
如需設定模型定義時可用選項的完整導覽,請參閱模型設定 (Model Settings)、屬性 (Attributes) 和 關聯 (Associations)。
一旦 Sails 應用程式開始執行,就可以從控制器動作 (controller actions)、helpers、測試以及您通常編寫後端程式碼的任何其他地方存取其模型。這讓您的程式碼可以呼叫模型方法來與您的資料庫(甚至多個資料庫)進行通訊。
模型上提供了許多內建方法,其中最重要的是模型方法,例如 .find() 和 .create()。您可以在參考 > Waterline (ORM) > 模型 (Models) 中找到這些方法的詳細使用說明文件。
Sails 中的每個模型都有一組公開的方法,讓您能夠以標準化的方式與資料庫互動。這是與應用程式資料互動的主要方式。
由於它們通常必須將查詢傳送到資料庫並等待回應,因此大多數模型方法都是非同步的。也就是說,它們不會立即傳回答案。就像 JavaScript 中的其他非同步邏輯(例如 setTimeout()
)一樣,這表示我們需要其他方法來判斷它們何時完成執行、是否成功,以及如果沒有成功,發生了什麼類型的錯誤(或其他異常情況)。
在 Node.js、Sails 和一般 JavaScript 中,建議的處理方式是使用 async/await
。
有關使用查詢的更多資訊,請參閱參考 > Waterline (ORM) > 查詢 (Queries)。
Sails 還提供了一些其他「資源型發布訂閱」(RPS) 方法,專門設計用於使用動態房間執行簡單的即時操作。有關這些方法的更多資訊,請參閱參考 > WebSockets > 資源型 PubSub (Resourceful PubSub)。
除了 Sails 提供的內建功能外,您還可以定義自己的自訂模型方法。自訂模型方法對於外推與特定模型相關的控制器程式碼最有用。它們允許將程式碼從控制器中提取出來,並插入到可從任何地方呼叫的可重複使用函式中(獨立於 req
或 res
)。
此功能利用了模型忽略無法辨識的設定這一事實,因此您確實需要小心,避免意外覆寫內建方法(例如,不要定義名為 "create" 的方法)。
如果您完全不確定,請改為編寫一個 helper。
自訂模型方法可以是同步或非同步函式,但通常情況下,它們是非同步的。依照慣例,非同步模型方法應為 async
函式,它接受一個 options
字典作為其引數。
例如
// in api/models/Monkey.js...
// Find monkeys with the same name as the specified person
findWithSameNameAsPerson: async function (opts) {
var person = await Person.findOne({ id: opts.id });
if (!person) {
throw require('flaverr')({
message: `Cannot find monkeys with the same name as the person w/ id=${opts.id} because that person does not exist.`,
code: 'E_UNKNOWN_PERSON'
});
}
return await Monkey.find({ name: person.name });
}
請注意,我們沒有在該函式中
try/catch
任何程式碼。那是因為我們打算將該責任留給呼叫我們函式的人。
然後您可以執行
var monkeys = await Monkey.findWithSameNameAsPerson({id:37});
如需更多提示,請閱讀關於 提摩西猴子 (Timothy the Monkey) 事件。
從 Sails v1.0 開始,實例方法已從 Sails 和 Waterline 中移除。雖然像 .save()
和 .destroy()
這樣的實例方法在應用程式程式碼中有時很方便,但在 Node.js 中,至少許多使用者發現它們導致了意想不到的後果和設計缺陷。
例如,考慮一個管理婚禮記錄的應用程式。在 Person 模型上編寫一個實例方法來更新資料庫中兩個人的 spouse
屬性似乎是一個好主意。這將允許您編寫如下的控制器程式碼
personA.marry(personB, function (err) {
if (err) { return res.serverError(err); }
return res.ok();
})
看起來很棒...直到需要實作一個邏輯大致相同,但唯一可用的資料是 "personA" 的 ID(而不是整個記錄)的稍微不同的動作時。在這種情況下,您還是只能將您的實例方法重寫為靜態方法!
更好的策略是從一開始就編寫一個自訂(靜態)模型方法。這使您的函式更具可重複使用性/通用性,因為無論您手邊是否有實際的記錄實例,都可以存取它。您可以將前一個範例中的程式碼重構為如下所示
Person.marry(personA.id, personB.id, function (err) {
if (err) { return res.serverError(err); }
return res.ok();
})
Sails v1.0 中的查詢不再強制為大小寫不敏感,無論資料庫如何處理查詢。這大大提高了查詢效能和更好的索引利用率。大多數資料庫預設為大小寫敏感,但在極少數情況下,如果它們不是,並且您想要更改該行為,則必須修改資料庫才能做到。
例如,MySQL 將預設使用大小寫不敏感的資料庫定序 (collation)。這與 sails-disk 不同,因此您可能會在開發到生產環境中遇到不同的結果。為了修正此問題,您可以將 MySQL 資料庫中的表格設定為大小寫敏感的定序,例如 utf8_bin
。