Изменение значений свойств модели в реакции паров 4 вручную - PullRequest
1 голос
/ 22 апреля 2020

У меня есть пар 4 приложения. Я делаю запрос из базы данных для получения некоторых элементов, и я хочу выполнить некоторые ручные вычисления на основе возвращенных значений до завершения запроса. Вот пример кода того, чего я пытаюсь достичь.

final class Todo: Model, Content {

    static var schema: String = "todos"

    @ID(custom: .id)
    var id: Int?

    @Field(key: "title")
    var title: String

    var someValue: Int?

}

/// Allows `Todo` to be used as a dynamic migration.
struct CreateTodo: Migration {
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        database.schema(Todo.schema)
            .field("id", .int, .identifier(auto: true))
            .field("title", .string, .required)
            .create()
    }

    func revert(on database: Database) -> EventLoopFuture<Void> {
        database.schema(Todo.schema).delete()
    }
}
final class TodoController:RouteCollection{

    func boot(routes: RoutesBuilder) throws {

        routes.get("tmp", use: temp)
    }

    func temp(_ req:Request) throws -> EventLoopFuture<[Todo]> {

        Todo.query(on: req.db).all().map { todos in

            todos.map {
                $0.someValue = (0...10).randomElement()!
                return $0
            }
        }
    }

}

Проблема в том, что эти изменения вручную не доступны в ответ. В этом случае someValue свойство.

Спасибо.

[
    {
        "title": "item 1",
        "id": 1
    },
    {
        "title": "item 2",
        "id": 2
    }
]

1 Ответ

2 голосов
/ 22 апреля 2020

Проблема, с которой вы столкнулись, состоит в том, что Model s переопределяет реализации Codable. Это позволяет вам делать такие вещи, как разносить родителей и не добавлять детей и т. Д. c.

Однако это нарушает ваш случай. Что вы должны сделать, это создать новый тип, если вы хотите вернуть Todo с другим полем, которое не хранится в базе данных, что-то вроде:

struct TodoResponse: Content {
  let id: Int
  let title: String
  let someValue: Int
}

, а затем преобразовать из вашего типа базы данных на ваш тип ответа в вашем обработчике маршрута (это довольно распространенный шаблон и рекомендуемый способ сделать это в Vapor)

...