给定一个控制器方法,该方法接受一个符合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'
。
这里有什么好的解决方案?
答案 0 :(得分: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 :(得分:1)
您收到的错误是因为您要保存(内容),需要保存请求:
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。因此,请确保在正文中发送Mission JSON时具有ID。