Using multiple projections in slick for the same table
I have a users table for which I would like to have multiple projections. For example, can I do something like
class Users(tag: Tag) extends Table [User] (tag, "user") {
def * = (id.?, emailId, firstName, lastName, gender) <> (User.tupled, User.unapply)
def allDetails = (id.?, emailId, firstName, lastName, gender, createdTime, modifiedTime)
...
}
I searched on Google but could not find anything. Can somebody tell me how can I use allDetails?
I'd like to do
object Users {
val users = TableQuery[Users]
def getAllDetails = ??? // How can I use allDetails here
}
+3
source to share
2 answers
Do the following:
class UserTable(tag: Tag) extends Table[UserInfo](tag, "user") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def emailId = column[String]("email_id", O.NotNull)
def firstName = column[String]("firstname")
def lastName = column[String]("lastname")
def gender = column[String]("gender")
def createdTime = column[Option[Timestamp]]("created_time")
def modifiedTime = column[Option[Timestamp]]("modified_time")
def userInfo = (emailId, firstName, lastName, gender, createdTime, modifiedTime, id.?) <> (User.tupled, User.unapply)
def * = (emailId, firstName, lastName, gender, id.?) <> (UserInfo.tupled, UserInfo.unapply)
}
case class User(emailId: String,
firstName: String, lastName: String, gender: String,
createdTime: Option[Timestamp],
modifiedTime: Option[Timestamp], id: Option[Int] = None)
case class UserInfo(emailId: String, firstName: String, lastName: String,
gender: String, id: Option[Int] = None)
for additional projection:
val userTable = TableQuery[UserTable]
def insert(userInfo: UserInfo) (implicit session: Session): Int = {
//return auto incremeted id
userTable returning (userTable.map(_.id)) += userInfo
}
def update(userInfo: UserInfo)(implicit session: Session) = {
userTable.filter(_.id === userInfo.id).update(userInfo)
}
def getUserInfo()(implicit session: Session): List[UserInfo] = {
userTable.list
}
0
source to share
Lately the same need has arisen and he started using something like this:
abstract class AnyUserTable[T](tag: Tag) extends Table[T](tag, "user") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def emailId = column[String]("email_id")
def firstName = column[String]("firstname")
def lastName = column[String]("lastname")
def gender = column[String]("gender")
}
class Users(tag: Tag) extends AnyUserTable[User](tag) {
def * = (emailId, firstName, lastName, gender, id.?) <> (User.tupled, User.unapply)
}
class UserDetails(tag: Tag) extends AnyUserTable[UserDetail](tag) {
def createdTime = column[Option[Timestamp]]("created_time")
def modifiedTime = column[Option[Timestamp]]("modified_time")
def * = (emailId, firstName, lastName, gender, createdTime, modifiedTime, id.?) <> (UserDetail.tupled, UserDetail.unapply)
}
object Users {
val users = TableQuery[Users]
val getAllDetails = TableQuery[UserDetails] // That is how I propose to get all the details
}
borrowing case classes from Sky's answer.
case class User(
emailId: String, firstName: String, lastName: String,
gender: String, id: Option[Int] = None)
case class UserDetail(
emailId: String,
firstName: String, lastName: String, gender: String,
createdTime: Option[Timestamp],
modifiedTime: Option[Timestamp], id: Option[Int] = None)
I guess this is pretty close to what I would like to try with updatable views in straight sql.
+6
source to share