Search code examples
swiftasynchronousfluentvapor

Create 1-to-1 relationship in Vapor Fluent asynchronously


Vapor Fluent question. I have the following code to save a User to a Postgres.

User
@Parent(key: FieldKeys.profile) var profile: Profile

...

let profile = User.Profile()
try await profile.save(on: request.db)
                            
if let profileID = try await User.Profile.query(on: request.db).all().last?.id {
    user.$profile.id = profileID; print("Profile created with ID=\(profileID)")
}
try await user.save(on: request.db)

My concern here is that another request could come in at the same time and create an entry in the Profile table and its id will have been returned as the last instead of the previous entry's id.

Is there a guaranteed way to create a user-profile relationship?


Solution

  • When you save a model in Fluent the ID is populated for you from the returned data in the query. So you can write

    let profile = User.Profile()
    try await profile.save(on: request.db)
    
    let profileID = try profile.requireID()         
    user.$profile.id = profileID
    try await user.save(on: request.db)
    

    You could also use one of the attach helpers from Fluent