Search code examples
scalaslickslick-3.0

Filtering on an option of a custom column in Slick 3.0.2


I am having some issues getting the following example to compile.

import scala.slick.driver.MySQLDriver.simple._

case class Age(value: Int)
case class User(id: Long, age: Option[Age])

object Dao {
  implicit val ageColumnType: TypedType[Age] = MappedColumnType.base[Age, Int](_.value, Age(_))

  class UserTable(tag: Tag) extends Table[User](tag, "users") {
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
    def age = column[Option[Age]]("age")
    def * = (id, age) <> (User.tupled, User.unapply)
  }

  val users = TableQuery[UserTable]
  def byId(id: Long)(implicit session: Session): Option[User] = {
    users.filter(_.age === Some(Age(21))).firstOption
  }
}

But the compiler is failing with the following error:

Example.scala:16:28: value === is not a member of slick.lifted.Rep[Option[Age]]

Does the right way to do this involve using OptionColumnExtensionMethods or something? It is strange that the type-classes for TypedType[Option[T]] would not kick in here, however.


Here is a list of some other resources I dug up, but none of them seem to deal with a container type around a custom column type using mappedColumnType.


Solution

  • Figured it out and figured it was worth posting here.


    The following line had too broad of a type signature.

    implicit val ageColumnType: TypedType[Age]
    

    Obviously, the implicit scope no longer contained the right evidence to infer the various column operators needed in the filter query, including the === method. Instead, I just needed a more specific type:

    implicit val ageColumnType: BaseColumnType[Age]
    

    As per the comment on the original question, the ==? solution also works once this change is made. Thanks!