Say I have a model like:
case class User(
id: Int,
name: String,
userType: Int)
Should I then do this:
sealed trait UserType
case object Member() extends UserType
case object Anonymous() extends UserType
I should also somehow associate a value for each UserType.
I would then change the User case class to have a UserType property instead of the int?
I guess then I would create a implicit converter for slick, which I believe would be a MappedColumnType from int to UserType.
Update This is for using slick db access.
I would do it the other way around. I would have a type for the user depending on the scenario that extends User:
sealed trait User
case class NormalUser(name: String, id: Int) extends User
case class SuperUser(name: String, id: Int, superPowers: Map[String, String]) extends User
And then pattern match on the actual User type when needed.
I'd go with enum:
object UserType extends Enumeration {
type UserType = Value
val Member = Value("Member")
val Anonymous = Value("Anonymous")
}
And the converter as you said:
implicit val userTypeColumnType = MappedColumnType.base[UserType, String](
userType => userType.toString,
UserType.withName
)
Then you can use userType: UserType in your User case class.
In table definition you can have def userType = column[UserType]("user_type")
Update One of the reasons for choosing enum over trait is that slick is not able to find this implicit converter when you do not put the supertype explicitly. E.g.
.filter(_.userType === Member)
yields
type mismatch;
[error] found : Member.type
[error] required: slick.lifted.Rep[?]
[error] .filter(_.userType === Member).result
But the following works
.filter(_.userType === Member.asInstanceOf[UserType])
.filter(_.userType === (Member : UserType))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With