播放光滑的更新枚举列

时间:2017-12-22 16:10:20

标签: scala playframework slick play-slick

我无法确定如何使用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工作正常。

1 个答案:

答案 0 :(得分:0)

您需要定义TestStatus.Value的自定义列类型。这就是如何通过将它映射到已经支持的类型来构建自定义列类型的方式:

implicit def testStatCT: BaseTypedType[TestStatus.Value] = 
  MappedColumnType.base[TestStatus.Value, String](
    enum => enum.toString, str => TestStatus.withName(str)
  )

这种隐式需要在任何隐式解决方案(例如示例中的隐式解析失败)(或者更好地在TestStatus对象中定义以便它始终可用)的任何地方导入,这样光滑的证据可以证明TestStatus.ValueBaseTypedType,基本上只是意味着某些内容是受支持的列类型。

有关列映射的进一步阅读,请查看Slick Documentation