Reputation:
I'm just getting started with programming and vapor and have the following querying problem.
When a user makes a request to /api/trip/new to create a new trip, I want to retrieve the first driver from the database and assign their ID to a Trip object. Then I want to save both the trip and trip request in the database.
I have the following code:
func newTripHandler(_ req: Request, data: TripRequestCreateData) throws -> Future<TripRequest> {
let passenger = try req.requireAuthenticated(Passenger.self)
let tripRequest = try TripRequest(pickupLat: data.pickupLat,
pickupLng: data.pickupLng,
destLat: data.destLat,
destLng: data.destLng,
pickupAddress: data.pickupAddress,
destAddress: data.destAddress,
passengerId: passenger.requireID())
//Passenger's location
let lat = tripRequest.pickupLat
let lng = tripRequest.pickupLng
//Passenger's destination
let toLat = tripRequest.destLat
let toLng = tripRequest.destLng
let trip = Trip(passengerId: tripRequest.passengerId!,
pickupLat: lat,
pickupLng: lng,
destLat: toLat,
destLng: toLng,
pickupAddress: tripRequest.pickupAddress,
destAddress: tripRequest.destAddress)
let driver = Driver.query(on: req).first().unwrap(or: Abort(.notFound))
let driverId = driver.map(to: Driver.self) { driver in
return driver.id
}
trip.driverId = driverId
print(trip)
return tripRequest.save(on: req)
}
struct TripRequestCreateData: Content {
let pickupLat: Double
let pickupLng: Double
let destLat: Double
let destLng: Double
let pickupAddress: String
let destAddress: String
}
I’m not sure how to save two models and how to properly retrieve the driver from the database. The driverId constant is of type EventLoopFuture instead of Driver so I can't assign the ID to trip's driverId property.
How can I adjust my code to achieve this?
Upvotes: 1
Views: 271
Reputation: 181
When working with the database, you only get Future
s. (More about Future
s in The Vapor Docs.)
So to get the driver, you already used the correct code, but have to go on inside the map
codeblock. When returning a Future
inside the map
, use flatMap
, so you don't have a Futures
inside Futures
.
Try this:
return Driver.query(on: req).first().unwrap(or: Abort(.notFound)).flatMap { driver in
trip.driverId = driver.id
return trip.save(on: req).flatMap { trip in
return tripRequest.save(on: req)
}
}
(I chose this way to show how Future
s work - there are some ways to make this code cleaner, e.g. chaining Future
s or using flatten
.)
Upvotes: 4