如何在 table 中拥有不必在 post 请求中指定的列

How to have columns in table that don't have to be specified in post request

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

例如,假设用户修补了一些新值,每次发生这种情况时,table 应该会自动用当前时间更新一列。

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

在 table 中包含不必由 post 请求指定的列的最惯用方法是什么?

我发现我需要在模型中将计算字段设为可选,然后在保存之前在路由函数中计算它们。

例如:

使 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)
    }

如果您只想更新已修改或创建的时间戳,那么还有其他两种方法。在您的模型中,输入:

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

让 vapor 为您完成,如果您正在更新不需要用户输入的字段,请参阅 here. Alternatively, you can make use of the methods willCreate, willUpdate, etc. as described in the docs here

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)