我无法确定如何使用play-slick更新类型枚举的列。
这是我的枚举和案例类:
object TestStatus extends Enumeration {
type TestStatus = Value
val Status1 = Value("Status1")
}
case class Test (
id: String,
status: TestStatus
)
和表映射:
class Tests(tag: Tag) extends Table[Test](tag, "tests") {
implicit val statusColumn = MappedColumnType.base[TestStatus, String](_.toString, TestStatus.withName)
override def * = (id, status) <> ((Test.apply _).tupled, Test.unapply)
val id = column[String]("id", 0.PrimaryKey)
val status = column[TestStatus]("status")
}
当我尝试去更新测试行时,我收到一个错误:
object TestQueries extends TableQuery[Tests](new Tests(_)) {
def updateStatus(id: String, newStatus: TestStatus) = {
TestQueries.filter(_.id === id).map(_.status).update(newStatus)
}
}
[error] Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection,
[error] you use an unsupported type in a Query (e.g. scala List),
[error] or you forgot to import a driver api into scope.
[error] Required level: slick.lifted.FlatShapeLevel
[error] Source type: slick.lifted.Rep[models.TestStatus.Value]
[error] Unpacked type: T
[error] Packed type: G
[error] TestQueries.filter(_.id === id).map(_.status).update(newStatus)
[error] ^
IntelliJ显示TestQueries.filter(_.id === id).map(_.status)
具有类型Query[Nothing, Nothing, Seq]
,这使我认为问题在于特定列而不是更新函数。
使用相同的结构更新id工作正常。
您需要定义TestStatus.Value
的自定义列类型。这就是如何通过将它映射到已经支持的类型来构建自定义列类型的方式:
implicit def testStatCT: BaseTypedType[TestStatus.Value] =
MappedColumnType.base[TestStatus.Value, String](
enum => enum.toString, str => TestStatus.withName(str)
)
这种隐式需要在隐式解决方案(如示例中的那个失败)(或者更好地在TestStatus
对象中定义以便它始终可用)的任何地方导入,这样光滑的证据可以证明TestStatus.Value
是BaseTypedType
,这基本上只是意味着什么是支持的列类型。
有关列映射的进一步阅读,请查看Slick Documentation