如何在Scala中将枚举类型绑定到路由?

3

我想在我的控制器中作为查询参数接收一个过滤列表,这个过滤列表也是一个枚举类型。我使用的是Scala语言的Play框架。问题是,IDE不认可将枚举类型作为查询参数。因此,我在路由文件中有如下代码:

GET /service-orders/ controllers.ServiceOrdersController.listServiceOrders(status: ServiceStatus)

我的枚举文件:

object ServiceStatus extends Enumeration {

  type ServiceStatus = Value

  val Pending = Value("pending")
  val Started = Value("started")
  val Completed = Value("completed")
  val Error = Value("error")
  
}

在 build.sbt 文件中,我尝试使用以下内容来向路由文件注入包

  routesImport ++= Seq(
      "serviceOrders.models.ServiceStatus"
    ),

我试过很多方法,但都没有成功。我在某个地方读到可以使用QueryStringBindable函数,但我无法让它正常工作...请问你们能帮我解决这个问题吗?

编辑:顺便问一下,有没有一种方法可以在不进行任何操作的情况下检查状态是否包含在一系列筛选器中?

.filter {
        serviceOrder =>
          status.map(serviceOrder.serviceStatus === _)
            .reduceOption(_ || _)
            .getOrElse(true: Rep[Boolean])
      }

这是我能想到的唯一方法,通过从 API 收到的查询参数列表来过滤状态。

你应该看一下enumeratum - cchantep
1个回答

2
您可以这样实现QueryStringBindable实例:
package serviceOrders.models

object ServiceStatus extends Enumeration {

  type ServiceStatus = Value

  val Pending = Value("pending")
  val Started = Value("started")
  val Completed = Value("completed")
  val Error = Value("error")

  implicit val queryStringBindable: QueryStringBindable[ServiceStatus] =
    new QueryStringBindable[ServiceStatus] {
      override def bind(
        key: String,
        params: Map[String, Seq[String]]
      ): Option[Either[String, ServiceStatus]] =
        params.get(key).collect {
          case Seq(s) =>
            ServiceStatus.values.find(_.toString == s).toRight("invalid value")
        }

      override def unbind(key: String, value: ServiceStatus): String =
        implicitly[QueryStringBindable[String]].unbind(key, value.toString)
    }
}

在 build.sbt 文件中,您需要添加以下内容:
routesImport ++= Seq("serviceOrders.models.ServiceStatus._")

在你的路由文件中添加以下内容:

GET     /some/route    controllers.SomeController.index(status: ServiceStatus)

接下来,您可以在SomeController中创建一个index方法,该方法需要一个ServiceStatus参数,并且Play将处理查询参数。

// 编辑: 实际上,您可以使用QueryStringBindable.Parsing类进一步简化实现。


非常感谢!我还没有测试过,但它非常有道理,并且对我来说是一个不错的解决方案。我会尽快将此实现结果反馈给我的项目。 - Matheus Martins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接