Swift & Vapor / Fluent: как извлечь значения из другой таблицы во время запроса после маршрутизатора

Я пишу серверное приложение на Xcode 11.2, используя Vapor3 и Fluent с SQLite. У меня есть маршрут для POST запроса на обновление записи в Table1, но прежде чем я сохраню запись, мне нужно извлечь значения из другой таблицы с ключом, который находится в одном из полей, которые я передаю. Часть, которую я ' m застревает в доступе к этим данным из другой таблицы.

Что у меня есть на данный момент:

Стол для персонала

final class Staff: Content, SQLiteUUIDModel, Migration, Parameter { 
  var id: UUID? 
  var staffID: String (value that's in the other table to match)
  var value1: Int (one of the values I'm trying to fetch)
  var value2: Int (another value I'm trying to fetch)
  ...(additional variables and Init

Таблица для заданий

final class Assignments: Content, SQLiteUUIDModel, Migration, Parameter {
  var id: UUID?
  var staffID: String 
  ...(additional variables and Init

Маршрут для входящего запроса POST для обновления существующего назначения:

router.post("update", Assignments.parameter) { req -> Future<Assignments> in
  return try req.parameters.next(Assignments.self).flatMap { Assignment in
  return try req.content.decode(Assignments.self).flatMap { updatedAssignment in

  (Code where I perform calculations on the incoming 'Assignment' and save to 'updatedAssignment' before calling:)

  return WorkOrder.save(on: req)

Маршрут, который у меня есть, работает, входящие данные изменяются и записываются в базу данных SQLite, однако есть несколько полей, в которых мне нужно выполнять вычисления или устанавливать значения, хранящиеся в таблице Staff. IE:


editedAssignment.variable = (variable) * (value1 from staff table for matching staffID)
editedAssignment.variable = (value2 from staff table for matching staffID)

Что я пробовал на данный момент

let staffData = Staff.query(on: req).filter(\.staffID == staffID).all() before the calculations
(adding as a Future as:)
router.post(...) { req -> Future<Staff> in return try Staff.query(on: req).filter ...(rest of query)  

- этот метод скидывает весь запрос, значения входящего запроса просто теряются.

В идеале, если бы я мог вызвать запрос и сохранить его как словарь в вычислениях, это было бы идеально, я просто не могу «понять это».


person RayleighRelentless    schedule 10.12.2019    source источник


Ответы (1)


Вам нужно поместить его в свой маршрут, чтобы он был частью цепочки, а не разъединенным, как у вас:

router.post("update", Assignments.parameter) {
    req -> Future<Assignments> in
    return try req.parameters.next(Assignments.self).flatMap {
        assignment in
        return try req.content.decode(Assignments.self).flatMap {
            updatedAssignment in
            return Staff.query(on: req).filter(\.staffID == staffID).first().flatMap {
                staffData in 
                /* Code to update 'updatedAssignment' */
                return WorkOrder.save(on: req)
            }
        }
    }
}

Скорее всего, вы получите ошибки компилятора и вам нужно будет указать явные возвращаемые типы, но я не могу их предсказать / проверить. Я оставил это, но я не думаю, что это хорошая идея, если вы явно укажете, что Future<Assignments> возвращается, когда вы заканчиваете с возвратом от WorkOrder.save....

person Nick    schedule 17.12.2019
comment
Вроде работает, я могу без ошибок строить. Мне нужно будет заполнить раздел и пропустить данные для тестирования. Что касается возврата WorkOrder.save, это была опечатка с моей стороны. Это должно было быть Assignment.save. - person RayleighRelentless; 02.01.2020
comment
Рад, что это работает. Принятие ответа поднимает его в рейтинге поиска и делает его более полезным для других пользователей. - person Nick; 18.02.2020