Как я могу получить это для понимания, чтобы вернуться?

Вопрос задан: 9 месяцев назад Последняя активность: 9 месяцев назад
up -1 down

Я создаю контроллер, который говорит на службу. Контроллер (который основан на библиотеке Play AbstractController) Принимает неявный запрос и возвращает Future[Result]. Служба принимает запрос и возвращает Future[Model]. У меня есть некоторые условия, которые я хочу, чтобы защититься от создания модели. Например, если пользователь не имеет доступа, то ни одна модель не должна быть создана.

 def create(): Action[JsValue] = Action(parse.tolerantJson).async { implicit request: Request[JsValue] =>
    val modelOpt: Option[Future[Result]] =  // I've tried Future[Result] here too
      for {
        attributes <- (request.body \ "data" \ "attributes").validate[JsObject].asOpt
        userOpt = (request.body \ "data" \ "attributes" \ "user-name").validate[String].asOpt
        user <- userOpt
        model <- service1.createModel(user) // Create Model returns type of Future[Model], so this should flatMap to Model
      } yield {
        val permission = checkPermission(user)  // Returns true or false, depending on if the user is permissioned
        (userOpt, permission) match {
          case (Some(_), true) => Ok(model)
          case (Some(_), false) => Forbidden
          case (None, _) => NotFound 
          case (_, false) => Forbidden 
        }
      }

    modelOpt.getOrElse(Future { InternalServerError })
  }

Тем не менее, компилятор жалуется о том, что он ожидает Option[Future[Result]] и получил Future[Result] (Вероятно, из-за моего поставляемого типа для modelOpt). Тем не менее, я думаю, что если Json не подтверждает это даст мне None, Поэтому я думаю, что внешний вид действительно должен быть вариантом. Может кто-нибудь показать мне, что происходит?

1 ответ

Возможно, для Вашего проекта будут необходимы бесплатные векторные карты. На нашем сайте представлены карты для всех стран.

Реклама

up 1 down

Если вы посмотрите на подпись метода getOrElse в черте Option[A]:

final def getOrElse[B >: A](default: => B): B

он разворачивает Option чтобы возвращать A или его надтип до B.

Теперь, с modelOpt Option[Future[Result]], применяя getOrElse с заданным значением типа по умолчанию Future[Result] (Или его подтип) приведет к Future[Result].

Подобно тому, как getOrElse работает, но хранение Option в месте, метод orElse имеет следующую подпись:

final def orElse[B >: A](alternative: => Option[B]): Option[B]

Таким образом, применяя orElse чтобы modelOpt как ниже возвратят хотел Option[Future[Result]]:

modelOpt.orElse(Some(Future.successful(InternalServerError)))

Обратите внимание, что Future.successful используются для обеспечения уже завершено будущего с указанным результатом.