Hey guys, I'm trying to recreate this app I wrote ...
# exposed
a
Hey guys, I'm trying to recreate this app I wrote with spring using Ktor and Exposed, and I'm following the tutorial for DAOs on the github, but I'm a little confused. My situation simplified is basically, I have a User model that has an ID and a reference to an Image model, I want to be able to do User.images and Image.user. So my user (simplified) is like
Copy code
class User(id: EntityID<Long>) : LongEntity(id) {
    var images by Image via UserImages

    companion object : LongEntityClass<User>(Users)
}
My image simplified is like
Copy code
class Image(id: EntityID<Long>) : LongEntity(id) {
    val user by User referencedOn Images.user

    companion object : LongEntityClass<Image>(Images)
}
And my tables are as follows
Copy code
object Images : LongIdTable() {
    val user = reference("user", Users)
}


object Users : LongIdTable() {
// Do I need to do something to establish a relationship to images here?
}

object UserImages : Table() {
    val user = reference("user", Users).primaryKey(0)
    val image = reference("image", Images).primaryKey(1)
}
I've been following the tutorial on the wiki, and I was fine with everything I think until I started trying to establish this relationship. I hope this isn't too much of a noob question, I just decided to try Kotlin yesterday after people scala-shaming me for months 😜.
t
Do you want to bind images to a single user (one-to-many relationship) or share images between users (many-to-many) ?
a
One user has many images that only belong to them
t
Then you don't need
UserImages
table. use
val images by Image.referrersOn(Images.user)
a
Sweet, didn't think it'd be that simple, thanks so much. Is the line establishing the relationship from the image side good, or should it be changed to something else?
Copy code
val user = reference("user", Users)
is what I'm referencing
t
Looks good for me:) I think you don't need to change anything else.
a
Sweet, thanks a lot!
hmm, how do i then add an image to the images collection? The github assigns a value in their example
Copy code
transaction {
  film.actors = SizedCollection(listOf(actor))
}
But doing so in my case is a problem, since changing images to
val
causes an error. I'd prefer to keep as much code immutable as possible, so how do I work around this?
t
You may rename
val
to
var
but I prefere to set user to a image in a creation time, like:
Copy code
val newImage = Image.new {
   ... 
   this.user = ownerOfImage
}
a
The wiki on the github said if I didn't want to manually give each object an ID value I had to do it in separate transactions, so I opted to, but actually I can set an Image's user no-problem, it's setting a User's Images that's the issue
Or is Images autopopulated by the user column in each image, do i not need to set it at all?
t
When you request
user.images
Exposed will load all
Image
instances where
user
column equals to
user.id
value. So when you create new Image and fill
user
field you automatically "update" result which will be returned by next
user.images
call.
a
Alright 😄 great to know thanks again