Reputation: 363
I'm trying to do a OneToOne relation between two tables using Exposed, I've created a User table and a UserSettings Table, I'd like to have the User table reference the UserSettings table. My question is how do I create the reference and create a user that has referenced settings?
UserTable
object UserTable : IntIdTable("user") {
val username = varchar("username", 16)
val email = varchar("email", 254)
val password = varchar("password_hash", 60)
val settings = reference("id", UserSettingsTable)
}
UserEntity
class User(id: EntityID<Int>): IntEntity(id), Principal {
companion object : IntEntityClass<User>(UserTable)
var username by UserTable.username
var email by UserTable.email
var password by UserTable.password
val settings by UserSettings referrersOn UserTable.settings
}
SettingsTable
object UserSettingsTable : IntIdTable("user_settings") {
var themeName = varchar("theme_name", 16).clientDefault {"dark"}
}
SettingsEntity
open class UserSettings(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<UserSettings>(UserSettingsTable)
var themeName by UserSettingsTable.themeName
}
This is what I was attempting to do to create an entry
User.new {
email = "[email protected]"
username = "Someone"
password = "test"
}.also { newUser ->
UserSettings.new(newUser.id.value) {
themeName = "dark"
}
}
Upvotes: 3
Views: 2460
Reputation: 2046
Here is a sample that I haven't tested:
object UserSettingsTable : IntIdTable("user_settings") {
var themeName = varchar("theme_name", 16).clientDefault {"dark"}
}
object UserTable : IntIdTable("user") {
val username = varchar("username", 16)
val email = varchar("email", 254)
val password = varchar("password_hash", 60)
val settings = reference("settings", UserSettingsTable)
}
class UserSettings(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<UserSettings>(UserSettingsTable)
var themeName by UserSettingsTable.themeName
}
class User(id: EntityID<Int>): IntEntity(id) {
companion object : IntEntityClass<User>(UserTable)
var username by UserTable.username
var email by UserTable.email
var password by UserTable.password
var settings by UserSettings referencedOn UserTable.settings
}
fun createUser(): User {
return User.new(1) {
email = "[email protected]"
username = "Someone"
password = "test"
settings = UserSettings.new(1) { themeName = "dark" }
}
}
Mind that referencedOn
is for simple references, while referrersOn
is for collections. Also, there is a limitation in the Exposed
Creating the entity and the reference in the same transaction does only work if you set the id column manually. If you're using UUIDTables and UUIDEntity you can do it like this:
transaction {
//only works with UUIDTable and UUIDEntity
StarWarsFilm.new (UUID.randomUUID()){
...
actors = SizedCollection(listOf(actor))
}
}
Upvotes: 4