更新模型以使请求体与Swift匹配的简明方法?

问题描述 投票:0回答:2

给定一个控制器方法,它接受符合Vapor中实体中某些或所有属性的请求体,是否有更新实体的方法而无需手动分配所有属性?目前,我必须这样做:

func update(_ req: Request) throws -> Future<Mission> {
    let mission = try req.parameters.next(Mission.self)
    let content = try req.content.decode(Mission.self)

    return flatMap(to: Mission.self, mission, content) { (mission, content) in
       mission.propertyA = content.propertyA
       mission.propB = content.propB
       mission.propC = content.propC
       return mission.save(on: req)
    }
}

这不是很可扩展,因为它需要我手动分配每个属性。我正在寻找的是这样的:

func update(_ req: Request) throws -> Future<Mission> {
    let mission = try req.parameters.next(Mission.self)
    let content = try req.content.decode(Mission.self)

    return mission.save(on: content)
}

然而,这会产生错误Argument type 'EventLoopFuture<Mission>' does not conform to expected type 'DatabaseConnectable'

这里有什么好的解决方案?

swift vapor
2个回答
1
投票

使用Submissions你应该能够做到:

func create(req: Request) throws -> Future<Either<Mission, SubmissionValidationError>> {
    return try req.content.decode(Mission.Submission.self)
        .updateValid(on: req)
        .save(on: req)
        .promoteErrors()
}

它需要一些设置,但它很灵活,允许您验证您的输入。结果中的promoteErrors函数+ Either有助于创建有用的错误响应,但您可以不使用它们。


1
投票

您收到的错误是因为您尝试保存(on:content),您需要保存请求:

return mission.save(on: req)

话虽这么说,你真正想要的是这个:

func update(_ req: Request) throws -> Future<Mission> {

    let updatedMission = try req.content.decode(Mission.self)

    return updatedMission.update(on: req)
}

这将解码请求正文中的Mission对象,然后使用数据库中的相应ID更新Mission。因此,请确保当您在身体中发送具有ID的Mission JSON时。

© www.soinside.com 2019 - 2024. All rights reserved.