Comparing type mapped values in Slick queries

scala, slick

Solution

When in doubt with Slick, go check out the unit tests. After reading their docs on mapping in a custom type and then looking at their unit tests, I got your query code to compile by changing it to:

def queryByFavoriteType(ftype : FavoriteType)(implicit s: Session) = {
  for(f <- Favorites if f.favoriteType === (ftype:FavoriteType)) yield f
}

Also, I had imported the `H2Driver` just to get things to compile (`import scala.slick.driver.H2Driver.simple._`). I was assuming that you also had imported whatever driver it is that you need for your db.

EDIT

My full code example is as follows:

import scala.slick.driver.PostgresDriver.simple._
import scala.slick.session.Session

sealed case class FavoriteType(mapping: String) {
  override def toString = mapping.capitalize
}

case class Favorite(ft:FavoriteType, foo:String)
object FavoriteType {
  object Exam extends FavoriteType("examen")
  object Topic extends FavoriteType("onderwerp")
  object Paper extends FavoriteType("profielwerkstuk")

  val values = Seq(Exam , Topic , Paper )
}

object Favorites extends Table[Favorite]("favorites") {
  // Convert the favoriteTypes to strings for the database
  implicit val favoriteMapping = MappedTypeMapper.base[FavoriteType, String](
    {favType => FavoriteType.values.find(_ == favType).get.mapping},
    {mapping => FavoriteType.values.find(_.mapping == mapping).get}
  )

  def favoriteType = column[FavoriteType]("type")
  def foo = column[String]("foo")

  def * = favoriteType ~ foo <> (Favorite.apply _, Favorite.unapply _)

  def queryByFavoriteType(ftype : FavoriteType)(implicit s: Session) = {
    for(f <- Favorites if f.favoriteType === (ftype:FavoriteType)) yield f
  }   
}

Problem

Consider the Favorites table object below, we want to write a query to find Favorites by their type (defined below). We have also defined a Typemapper, to map a FavoriteType to a String for the database ``` import scala.slick.driver.PostgresDriver.simple._ //Other imports have been omitted in this question object Favorites extends Table[Favorite]("favorites") { // Convert the favoriteTypes to strings for the database implicit val favoriteMapping: TypeMapper[FavorietType] = MappedTypeMapper.base[FavorietType, String]( favType => FavorietType.values.find(_ == favType).get.mapping, mapping => FavorietType.values.find(_.mapping == mapping).get ) def favoriteType = column[FavoriteType]("type") //other columns here ``` This is the query I want to write (however it does not compile) ``` def queryByFavoriteType(ftype : FavoriteType)(implicit s: Session) = { for( f <- Favorieten if f.favoriteType === ftype ) yield f } } ``` Here I have defined de different FavoriteType objects (this is outside the Favorieten Object) ``` sealed case class FavorietType(mapping: String) { override def toString = mapping.capitalize } object FavoriteType { object Exam extends FavoriteType("examen") object Topic extends FavoriteType("onderwerp") object Paper extends FavoriteType("profielwerkstuk") val values = Seq(Exam , Topic , Paper ) } ``` The problem I have here is that the query does not compile: `value === is not a member of scala.slick.lifted.Column[models.gebruiker.FavorietType]` It appears that === can not be used to compare a User-defined type, is this true? Is there an alternative way to do this? Edit Related issue: before I had my TypeMapper without explicit type, it was defined as `implicit val favoriteMapping = MappedTypeMapper.base[FavorietType, String]( ...` When I would write a query that would compare a FavoriteType.Exam (for example) such as ``` def queryByFavoriteExam()(implicit s: Session) = { for(f <- Favorieten if f.favorietType === FavorietType.Exam) yield f } ``` This would result in the error `could not find implicit value for evidence parameter of type scala.slick.lifted.TypeMapper[models.gebruiker.FavorietType.Exam.type]` The solution for this is the same as the one presented below

Original source