Vapor: Checking for duplicate Objects before saving onto DB

I want to make a duplicate check in my createHandler for myModelController.

My initial idea was to initialize the object: let object = try Object(...)
then query all the objects ( Object.query(on: req).all().flatMap { objects in ... }) and iterate through the objects array
then compare properties …

I was wondering if there was an easier way to do this with Vapor and Fluent queries?

This was my solution for anyone in the future who has the same question :+1:

     func create(_ req: Request, data: firebaseTokenCreateData) throws -> Future<FirebaseToken> {
        let user = try req.requireAuthenticated(User.self)
        let firebaseToken = try FirebaseToken(deviceToken: data.deviceToken, firebaseToken: data.firebaseToken, userID: user.requireID())
        
        return FirebaseToken.query(on: req).filter(\.firebaseToken == firebaseToken.firebaseToken).first().flatMap(to: FirebaseToken.self) { existingFBToken in
            // return existing token calling update or saves new token if didn't already exist
            return existingFBToken?.update(on: req) ?? firebaseToken.save(on: req)
        }
    }

@gflo Thank you for sharing your solution - much appreciated! :]

@gflo Don’t know if this would help you but there is a better solution for that by just tell vapor to take care of it through Migration. Here is an example:

 extension User: Migration {
    static func prepare(on connection: MySQLConnection) -> Future<Void> {
        return Database.create(self, on: connection) { (builder) in
            try addProperties(to: builder)
            builder.unique(on: \.username)
            builder.unique(on: \.email)
        }
    }
}
1 Like