Does setting a .unique(on:) constraint affect the uniqueness of the .id in fluent/vapor?

66 Views Asked by At

As the title says:

Does setting a .unique(on:) affect the .id in fluent/vapor?

I have a "user" schema which has a .id and is also .unique(on: email). Now I have noticed that I have entries of users in the database which have different email addresses but the same ids. I thought that this should not happen because ids are also unique.

Maybe someone has an answer for me. Thanks a lot already!

struct CreateUser: Migration {
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        
    database.schema(User.schema)
        .id()
        .field("name", .string)
        .field("email", .string, .required)
        .unique(on: "email")
        .create()
    }
    
    func revert(on database: Database) -> EventLoopFuture<Void> {
        database.schema(User.schema)
            .delete()
    }
}

The only explanation I can think of is that email and id are combined to form a primary key, or that the unique of the id is cancelled.

final class User: Model, Content {
static let schema = "users"

@ID                                             var id: UUID?
@Field(key: "email")                            var email: String
@Field(key: "name")                             var name: String?
    
init() {}

init(id: UUID? = nil,
     name: String?,
     email: String
) {
    self.id = id
    self.name = name
    self.email = email.lowercased()
}

}

1

There are 1 best solutions below

5
Nick On

You need to change the line @ID in your model to:

 @ID(key: .id) var id: UUID?

And then re-create the table - I.e. revert and run the migration again. I believe your problem is that vapor is not ending up making the id field the primary (and therefore unique) identifier. You can confirm this by looking at the table structure in the database.