如何在表中具有不必在请求后指定的列

时间:2019-08-18 21:00:29

标签: vapor

我有一个Vapor应用程序,我希望在POST请求中由用户指定一些值,并根据用户指定的值来计算其他值。

例如,假设用户使用一些新值打补丁,并且每次发生该表时,该表应自动使用当前时间更新一列。

我一直在试图将计算出的属性存储在数据库中,但是当我修改模型以了解计算出的属性时,我所有的POST请求都开始期望指定这些属性。

在表中具有无需邮寄请求指定的列的最惯用的方法是什么?

2 个答案:

答案 0 :(得分:2)

如果您只想更新修改或创建的时间戳,则还有另外两种方法。在您的模型中,输入:

static let createdAtKey: TimestampKey? = \.createdAt
static let updatedAtKey: TimestampKey? = \.updatedAt
var createdAt:Date?
var updatedAt:Date?

让蒸气为您做这件事,请参阅here。或者,如果您要更新不需要用户输入的字段,则可以使用文档here中所述的方法willCreatewillUpdate等。

extension User
{
    func willUpdate(on connection: Database.Connection) throws -> Future<User>
    {
        modifiedCount += 1
        return Future.map(on: connection) { self }
    }
}

最后,如果您需要比自己的解决方案更多的灵活性,请考虑在控制器中使用它:

struct EditUserForm:Content
{
    let id:Int
    let surname:String
    let initials:String
}

func save(_ request:Request) throws -> Future<View>
{
    return try request.content.decode(EditUserForm.self).flatMap
    {
        newUserData in
        return try request.parameters.next(User.self).flatMap
        {
            originalUser in
            // update fields as required, EditUserForm only has a subset
            return originalUser.save(on:request).transform(to:try self.index(request))
        }
    }
}

您将需要常规路线:

router.post(User.parameter, "save", use:userController.save)

答案 1 :(得分:1)

我发现我需要使计算出的字段在模型中成为可选字段,然后在保存之前在route函数中对其进行计算。

例如:

在模型中使modified_date是可选的:

final class MyContentType: PostgreSQLModel {
    var id: Int?
    var name: String
    var modified_date: Date?
}

modified_date设置为计算值:

    func create(_ request: Request, content: MyContentType) throws -> Future< MyContentType > {
        content.modified_date = Date()
        return content.save(on: request)
    }