Как привязать enum к маршрутам с использованием scala? - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь получить список фильтров в качестве параметра запроса на получение, который также является перечислением на моем контроллере. Для этого я использую игровой фреймворк с scala. Проблема в том, что я не могу указать тип перечисления в качестве параметра запроса, потому что 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.

1 Ответ

1 голос
/ 14 июля 2020

Вы можете реализовать экземпляр 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)

Затем вы можете создать метод index, который принимает параметр ServiceStatus в SomeController, а Play позаботится о параметрах запроса.

// edit: вы действительно можете использовать класс QueryStringBindable.Parsing для дальнейшего упрощения реализации.

...