I have a table named profile, and my model here:
final class Profile: Model, Content {
struct Keys {
static let userId: FieldKey = "user_id"
static let nickname: FieldKey = "nickname"
static let bio: FieldKey = "bio"
}
static let schema = "profile"
@ID(key: .id) var id: UUID?
@Field(key: Keys.nickname) var nickname: String?
@Field(key: Keys.bio) var bio: String?
@Parent(key: Keys.userId) var user: User
init() {}
init(id: UUID? = nil, nickname: String?, bio: String?, userId: User.IDValue) {
self.id = id
self.nickname = nickname
self.bio = bio
self.$user.id = userId
}
}
And I got request body content from client like this:
{
"bio": "my new bio"
}
What I want is for the client to update whichever property it passes, there is my code to do this:
let userId = try req.auth.require(User.self).requireID()
guard let oldProfile = try await Profile.query(on: req.db).filter(\.$user.$id == userId).first() else {
let newProfile = Profile(nickname: edit.nickname, bio: edit.bio, userId: userId)
try await newProfile.save(on: req.db)
return GlobalResponse(code: .ok, msg: .custom("save success"))
}
if let b = edit.bio {
oldProfile.bio = b
}
if let n = edit.nickname {
oldProfile.nickname = n
}
try await oldProfile.update(on: req.db)
return GlobalResponse(code: .ok, msg: .custom("save success"))
Those code works fine, but is there a better or easier way to do this? I did not find a easy way to do upsert work.
I just started learning vapor.
I try to find some upsert code in vapor fluent, did comes nothing.
Fluent does not currently support upserts, primarily because of the complexities of supporting it in all supported databases in a generic way.
You can drop down to SQLKit to perform the upserts however, that will work fine.