davenportw15
davenportw15

Reputation: 157

Converting scala.slick.lifted.Query to a case class

I have a slick table "UserSchema" as follows:

class UserSchema(tag: Tag) extends Table[User](tag, "users") {

  def name = column[String]("name", O.NotNull)
  def password = column[String]("password", O.NotNull)
  def graduatingYear = column[Int]("graduating_year", O.NotNull)
  def id = column[Int]("id", O.NotNull, O.PrimaryKey, O.AutoInc)

  def * = (name, password, graduatingYear, id.?) <> (User.tupled, User.unapply)

}

My "User" case class is as follows:

case class User(name: String, password: String, graduatingYear: Int, id: Option[Int] = None)

I have a TableQuery[UserSchema] in a users object, and a database in a db object.

How can I convert the following into a User object?

db withSession { implicit session =>
  users.filter(_.id === 1)
}

At the moment, I have

db withSession { implicit session =>
    val list = users.filter(_.id === id).list
    list(0)
}

which works, but seems ugly to me. Is there a better way to do this?

Thanks for the help.

Upvotes: 0

Views: 2766

Answers (2)

Ende Neu
Ende Neu

Reputation: 15773

The list() method returns a List[User] but if you are only interested in the first entry use firstOption:

db withSession { implicit session =>
  val users = TableQuery[UserSchema]
  val someUser: Option[User] = users.filter(_.id === id).firstOption
}

Which returns Some(User) if the query found something, else None, this is also more safe as it could happen that the query has no result and calling list(0) could result in an exception.

Upvotes: 1

kdrakon
kdrakon

Reputation: 172

You can use a map on the Slick query like this:

db withSession { implicit session =>
  val userlist = users.filter(_.id === id).list
    .map(user => User(user._1, user._2, user._3, Some(user._4)))
}

where userlist is a collection of User.

Upvotes: 1

Related Questions