vapor學(xué)習(xí)教程-Model

Model


Model是任何應(yīng)用程序模型的基本協(xié)議,特別是要持久化的模型。

Model僅適用于Vapor,在Fluent里等價于Entity

Example


我們來創(chuàng)建一個簡單的用戶模型

final class User {
    var name: String

    init(name: String) {
        self.name = name
    }
}

符合模型的第一步要導(dǎo)入VaporFluent。

import Vapor
import Fluent

然后添加一致性到你的類。

final class User: Model {
    ...
}

接著編譯器通知你需要實現(xiàn)一些方法。

ID


第一個必需屬性是一個標(biāo)識符。當(dāng)從數(shù)據(jù)庫中獲取模型時,此屬性將包含標(biāo)識符。如果為nil,則保存模型時將被設(shè)置。

final class User: Model {
    var id: Node?
    ...
}

Node Initializable


下一個要求是從持久化數(shù)據(jù)創(chuàng)建模型的方法。模型使用NodeInitializable來實現(xiàn)這一點。

final class User: Model {
    init(node: Node, in context: Context) throws {
        id = try node.extract("id")
        name = try node.extract("name")
    }
    ...
}

idname是我們預(yù)期數(shù)據(jù)庫中的列或字段而被命名的。提取調(diào)用方法被標(biāo)記為嘗試,因為如果值不存在或者錯誤類型,它將拋出錯誤。

Node Representable


現(xiàn)在我們已經(jīng)涵蓋了初始化模型。我們需要顯示如何將其保存回數(shù)據(jù)庫。模型使用NodeRepresentable來實現(xiàn)這一點。

final class User: Model {
    func makeNode(context: Context) throws -> Node {
        return try Node(node: [
            "id": id,
            "name": name
        ])
    }
    ...
}

保存用戶時,將調(diào)用makeNode()方法,并將生成的節(jié)點保存到數(shù)據(jù)庫。idname是我們預(yù)期數(shù)據(jù)庫中的列或字段而被命名的。

在大多數(shù)情況下,不需要關(guān)心makeNode(context :)方法的上下文參數(shù)。它是協(xié)議的一部分,允許在更高級或特定場景中進行擴展。

Preparations


一些數(shù)據(jù)庫(如MySQL)需要為新模式做好準備。在MySQL中,這意味著創(chuàng)建一個新的表。準備工作也等同于遷移,因為它們可以用于在已創(chuàng)建模式之后更改模式。

Prepare


假設(shè)我們正在使用SQL數(shù)據(jù)庫。要為我們的User類準備數(shù)據(jù)庫,我們需要創(chuàng)建一個表。如果使用的數(shù)據(jù)庫如Mongo,可以不用實現(xiàn)這個方法。

final class User {
    static func prepare(_ database: Database) throws {
        try database.create("users") { users in
            users.id()
            users.string("name")
        }
    }
    ...
}

創(chuàng)建一個名為users的表,該表具有一個標(biāo)識符字段和一個具有鍵名稱name的字符串字段。這與init(node:Node)makeNode() - > Node方法相匹配。

Revert


可以創(chuàng)建可選的準備還原。如果vapor run prepare --revert被調(diào)用,則這個將被執(zhí)行。

final class User {
    static func revert(_ database: Database) throws {
        try database.delete("users")
    }
    ...
}

上面是刪除users表。

Preparations as Migrations


如果要在創(chuàng)建初始模式后將表單添加到表中,可以創(chuàng)建符合Preparation的結(jié)構(gòu)或類,如下所示:

struct AddFooToBar: Preparation {
    static func prepare(_ database: Database) throws {
        try database.modify("bars", closure: { bar in
            bar.string("foo", length: 150, optional: false, unique: false, default: nil)
        })
    }

    static func revert(_ database: Database) throws {

    }
}

然后,在Droplet設(shè)置中,添加以下行:drop.preparations.append(AddFooToBar.self)

Droplet


要在應(yīng)用程序引導(dǎo)時運行這些準備工作,必須將Model添加到Droplet

let drop = Droplet()
drop.preparations.append(User.self)

注意:在Droplet運行前必須附上準備工作。

Full Model


這就是最終的users模型:

import Vapor
import Fluent

final class User: Model {
    var id: Node?
    var name: String

    init(name: String) {
        self.name = name
    }

    init(node: Node, in context: Context) throws {
        id = try node.extract("id")
        name = try node.extract("name")
    }

    func makeNode(context: Context) throws -> Node {
        return try Node(node: [
            "id": id,
            "name": name
        ])
    }

    static func prepare(_ database: Database) throws {
        try database.create("users") { users in
            users.id()
            users.string("name")
        }
    }

    static func revert(_ database: Database) throws {
        try database.delete("users")
    }
}

Interacting


現(xiàn)在users符合Model,它有很多新的方法,如find(),query()makeJSON()等等。

Fetch


Models can be fetched by their database identifier
中文(簡體)
模型可以通過其數(shù)據(jù)庫標(biāo)識符獲取

let user = try User.find(42)

Save


新創(chuàng)建的模型可以保存到數(shù)據(jù)庫。

var user = User(name: "Vapor")
try user.save()
print(user.id) // prints the new id

Delete


具有標(biāo)識符的持久模型可以被刪除。

try user.delete()

Model vs. Entity


模型有幾個額外的一致性而FluentEntity就沒有。

public protocol Model: Entity, JSONRepresentable, StringInitializable, ResponseRepresentable {}

從協(xié)議中可以看出,VaporModel自動轉(zhuǎn)換為JSON,Response,甚至可以用于類型安全路由。

Options


更改表/集合名稱.

static var entity = "new_name"

繼續(xù)學(xué)習(xí)vapor學(xué)習(xí)教程-目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容