2

我正在尝试创建一个 ActionBuilder 来检查用户是否已登录,如果是,则将用户对象添加到请求中(AuthenticatedRequest)。使用 MySQL 这很容易,因为解析用户不会得到 Future 对象。但在这种特殊情况下,我们将 MongoDB 与 ReactiveMongo 一起用于 Play,它确实返回了一个未来值。

到目前为止,我已经在这里制作了这个小片段。但它给我一个类型不匹配:

类型不匹配; 找到:scala.concurrent.Future[Option[models.User]] => scala.concurrent.Future[Object] 需要:Object =>?

object Authenticated extends ActionBuilder[AuthenticatedRequest] {


def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
    import models.User
    (for{
      sID <- request.session.get("sessionID")
      code <- request.session.get("otherCode")
      user: Future[Option[User]] <- models.Session.getUserBySessionAndCode(sID, code)
    } yield {
      (for{
        uAbs <- user
      } yield {
        if(uAbs.isDefined) {
          block(AuthenticatedRequest(uAbs.get, request))
        }else{
          BadRequest
        }
      })
    }).getOrElse(Future.successful(BadRequest))
  }
}

你知道如何从这里继续前进吗?也许这甚至是错误的方法。谢谢!

4

1 回答 1

1

如何将步骤分成更小的块并按照您期望的类型明确键入它们,这样会更清晰,您会发现您的想法和所写的内容朝着不同的方向发展,例如:

def userFromRequest(request: Request): Future[Option[User]] = 
  for{
    sID <- request.session.get("sessionID")
    code <- request.session.get("otherCode")
    maybeUser <- models.Session.getUserBySessionAndCode(sID, code)
  } yield maybeUser

def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
  userFromRequest(request).flatMap {
    case None => Future.successful(BadRequest)
    case Some(user) => block(AuthenticatedRequest(user, request))
  }
}
于 2014-03-18T19:21:41.233 回答