Как сохранить модель с ребенком и вернуть сохраненную модель с ребенком в ответ в Vapor 3 - PullRequest
1 голос
/ 26 февраля 2020

Я пытаюсь написать функцию контроллера, чтобы одновременно вставить модель с дочерней моделью и получить такой же ответ JSON в ответ, но заполненный данными, добавленными из базы данных (то есть автоматически сгенерированным идентификатором). ).

Для приведенного ниже упрощенного примера тело запроса JSON будет выглядеть следующим образом:

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

Я ожидаю следующий ответ:

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

Приведенный ниже код, к сожалению, не компилируется, в сообщении об ошибке говорится: «Невозможно преобразовать выражение типа« EventLoopFuture »в тип возврата« 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)
                }
            }
        }
    }
}

1 Ответ

2 голосов
/ 26 февраля 2020
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)
            }
        }
    }
}
...