【问题标题】:How to save a model with a child and get the saved model with child back as a response in Vapor 3如何在 Vapor 3 中保存带有孩子的模型并将保存的带有孩子的模型作为响应
【发布时间】:2020-02-25 21:21:46
【问题描述】:

我正在尝试编写一个控制器函数来同时插入一个带有子模型的模型并获得相同的 JSON 响应作为回报,但填充了从数据库添加的数据(即自动生成的 id)。

对于下面的简化示例,JSON 请求正文如下所示:

{
    "field1": "blabla",
    "subContent": {
        "field2": "lalala"
    }
}

我期待以下回复:

{
    "id": 5,
    "field1": "blabla",
    "subContent": {
        "id": 44,
        "field2": "lalala"
    }
}

不幸的是,下面的代码无法编译,错误消息显示“无法将'EventLoopF​​uture'类型的表达式转换为'Response'类型。这发生在线

return subModel.create(on: req).flatMap { savedSubModel ->

代码如下:

struct MainContent: Content {
    var id: UUID?
    var field1: String
    var subContent: SubContent
}

struct SubContent: Content {
    var id: UUID?
    var field2: String
}

final class Controller {
    func create(_ req: Request) throws -> EventLoopFuture<Response> {
        return try req.content.decode(MainContent.self).map { request in
            let subModel = SubModel(
                field2: request.subContent.field2
            )
            return subModel.create(on: req).flatMap { savedSubModel -> EventLoopFuture<Response> in
                let mainModel = mainModel(
                    subModelId: savedSubModel.id!,
                    field1: request.field1
                )
                return mainModel.create(on: req).flatMap { savedMainModel -> EventLoopFuture<Response> in
                    let content = MainContent(
                        id: savedMainModel.id,
                        field1: savedMainModel.field1,
                        subContent: SubContent(
                            id: savedSubContent.id,
                            field2: savedSubContent.field2
                        )
                    )
                    return content.encode(status: .created, for: req)
                }
            }
        }
    }
}

【问题讨论】:

  • 既然你刚开始,我建议切换到 Vapor4,因为它的核心是稳定的,因为它基于 NIO2,它已经发布了很长时间。
  • 我实际上开始尝试 Vapor 4,但当前版本甚至无法编译。
  • 它是可编译的,但 Fluent4 需要 Swift 5.2,所以如果你想在 Fluent 中使用它,你必须安装最新的 beta Xcode 或从 swift.org 下载 Swift 5.2,然后你就可以在您当前版本的 Xcode 中选择它。或者另一种选择是在没有 Fluent 的情况下将我的 Bridges 库与 SwifQL 一起使用。 github.com/SwifQL/Bridges 但它是为那些想处理 SQL 的人准备的。
  • 我上周使用最新版本的 XCode 进行了尝试,并按照 beta 文档中的指南进行操作。所有框架库都可以下载,但是在构建时我在框架中遇到了一些编译错误(我认为是 Fluent 2.0)。所以我决定回到一个稳定的版本。我希望有一些很好的教程来从V3升级到V4。
  • 您确定您使用的是 Swift 5.2 吗?因为来自 AppStore 的最新非测试版 Xcode 在 Swift 5.1.3 上,您需要从开发者门户获取测试版 Xcode 或从 swift.org 下载 Swift 5.2

标签: swift vapor


【解决方案1】:
struct MainContent: Content {
    var id: UUID?
    var field1: String
    var subContent: SubContent
}

struct SubContent: Content {
    var id: UUID?
    var field2: String
}

final class Controller {
    func create(_ req: Request) throws -> EventLoopFuture<Response> {
        return try req.content.decode(MainContent.self).flatMap { request in
            let subModel = SubModel(
                field2: payload.subContent.field2
            )
            return subModel.create(on: req)
        }.flatMap { savedSubModel in
            let mainModel = mainModel(
                subModelId: try savedSubModel.requireID(),
                field1: request.field1
            )
            return mainModel.create(on: req).flatMap { savedMainModel in
                let content = MainContent(
                    id: try savedMainModel.requireID(),
                    field1: savedMainModel.field1,
                    subContent: SubContent(
                        id: try savedSubModel.requireID(),
                        field2: savedSubModel.field2
                    )
                )
                return content.encode(status: .created, for: req)
            }
        }
    }
}

【讨论】:

  • 你真是个天才!谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
  • 2013-07-17
  • 1970-01-01
  • 2015-04-17
  • 2013-02-08
  • 1970-01-01
相关资源
最近更新 更多