Reputation: 21
I'm writing a backend app in Xcode 11.2
using Vapor3
and Fluent
with SQLite
. I have a route for a POST
request to update a record in Table1, but before I save the record, I need to pull values from another table with a key that's in one of the fields I'm passing in. The part that I'm getting stuck on is accessing that data from the other table.
What I have so far:
Table for staff
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
Table for assignments
final class Assignments: Content, SQLiteUUIDModel, Migration, Parameter {
var id: UUID?
var staffID: String
...(additional variables and Init
Route for incoming POST request to update existing Assignment:
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)
The route I have works, incoming data is modified and written to the SQLite database, however there are a couple of fields that I need to perform calculations on or set to values stored in the Staff table. IE:
editedAssignment.variable = (variable) * (value1 from staff table for matching staffID)
editedAssignment.variable = (value2 from staff table for matching staffID)
What I've tried so far
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)
-- this method throws off the whole request, the values of the incoming request are just lost.
Ideally, if I could call a query and save as a dictionary in the calculations, that would be ideal, I just can't seem to "figure it out".
Upvotes: 1
Views: 479
Reputation: 5180
You need to put it inside your route, so that it is part of the chain, rather than disjointed as you had it:
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)
}
}
}
}
You will most likely get compiler errors and need to put explicit return types in, but I can't predict/test these. I've left it in, but I don't think it is a good idea that you are explicitly stating a Future<Assignments>
is being returned when you end up with the return from WorkOrder.save...
.
Upvotes: 2