问题
I'm having some difficulties querying/filtering in Slick 2.1.0 when using a custom column type. A simplified version of my problem:
import scala.slick.driver.MySQLDriver.simple._
sealed class Status(val intValue: Int)
case object Active extends Status(1)
case object Disabled extends Status(2)
case object Deleted extends Status(3)
case class TableMapping(id: Long, status: Status)
class MyTableDefinition(tag: Tag) extends Table[TableMapping](tag, "sometable") {
implicit val statusColumnType = MappedColumnType.base[Status, Int](statusToInt, intToStatus)
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def status = column[Status]("STATUS", O.NotNull, O.Default(Active))
def * = (id, status) <> (TableMapping.tupled, TableMapping.unapply)
private def statusToInt(s: Status): Int = s.intValue
private def intToStatus(i: Int): Status = i match {
case 1 => Active
case 2 => Disabled
case _ => Deleted
}
}
class MyTableDao {
val Items = TableQuery[MyTableDefinition]
def byId(id: Long)(implicit session: Session): Option[TableMapping] = {
Items.filter(_.status =!= Deleted).firstOption
}
}
I get a compile error on this:
Items.filter(_.status =!= Deleted).firstOption
The error states:
value =!= is not a member of scala.slick.lifted.Column[Status]
[error] def byId(id: Long)(implicit session: Session): Option[TableMapping] =
Items.filter(_.status =!= Deleted).firstOption
Any ideas of what I'm doing wrong? Maybe there is a much better way of doing this that I'm not aware of?
回答1:
The thing is that the Scala compiler will look for an implicit convertion for Deleted.type
instead of Status
.
As Deleted
is declared as an object
it is not a class, its actual class is Deleted.type
, so you just have to help the compiler to understand that is actually a Status
. How? You can try
class MyTableDao {
val Items = TableQuery[MyTableDefinition]
def byId(id: Long)(implicit session: Session): Option[TableMapping] =
Items.filter(_.status =!= Deleted.asInstanceOf[Status]).firstOption
}
That'll do it.
Let me know if it did work, I'm facing a similar problem and I was able to get rid of it doing that.
回答2:
Your custom type mapper needs to be in scope for the DAO; I'd do something like:
trait MyTypeMapper {
protected implicit val statusColumnType =
MappedColumnType.base[Status, Int](_.intValue, intToStatus)
private def intToStatus(i: Int): Status = i match {
case 1 => Active
case 2 => Disabled
case _ => Deleted
}
}
and then mix the trait into your table mapper and dao:
class MyTableDefinition(tag: Tag)
extends Table[TableMapping](tag, "sometable")
with MyTypeMapper {...}
class MyTableDao extends MyTypeMapper{...}
来源:https://stackoverflow.com/questions/30483811/filtering-when-using-custom-column-type-in-slick