如何向模型添加额外的 属性?

How do I add an additional property to a Model?

我有一个 Model 符合 Content:

import Vapor
import Fluent

final class User: Model, Content {
    static let schema = "user"
    
    @ID(key: .id)
    var id: UUID?

    @Field(key: "email")
    var email: String

    init() { }

    init(id: UUID? = nil, email: String) {
        self.id = id
        self.email = email
    }
}

这可以从数据库中获取并直接从路由返回,因此客户端接收用户为 JSON。

现在我想给用户添加一个额外的属性,它不存储在数据库中而是一个固定值或者在用户从数据库加载后才添加:

final class User: Model, Content {
    // ...
    var someOther: String = "hello"
    // ...
}

final class User: Model, Content {
    // ...
    var someOther: String? // set later
    // ...
}

现在的问题是这个属性从来没有添加到JSON,所以客户端只得到用户的idemail不是 someProperty。我该如何解决这个问题?

当您想要从您的客户端发送或接收与您的模型具有不同表示的数据时,通常的做法是定义一个自定义类型,然后您可以将其与模型类型相互转换。

鉴于此,您将定义一个新的 User.Response 类型,该类型符合 Content 而不是 User 模型,并且 return 来自您的路线。

extension User {
    struct Response: Content {
        let id: UUID
        let email: String
        let otherValue = "Hello World"
    }
}


func user(request: Request) throws -> EventLoopFuture<User.Response> {
    return User.find(UUID(), on: request.db).flatMapThrowing { user in
        guard let id = user.id else {
           throw Abort(.internalServerError, "User is missing ID")
        }

        return User.Response(id: id, email: user.email) 
    }
}

您添加的附加值未从您的模型编码的原因是因为模型类型的默认编码器迭代字段属性并对这些属性进行编码,因此如果您有一个 属性不要使用 IDFieldParentChildren 或其他字段 属性 包装器之一,它不会被编码。