我正在尝试创建一个ActionBuilder来检查用户是否已登录,如果是,则将用户对象添加到请求(AuthenticatedRequest)。使用MySQL这很容易,因为解析用户不会得到Future对象。但在这种特殊情况下,我们使用带有ReactiveMongo for Play的MongoDB,它会返回未来值。
到目前为止,我已经在这里制作了这个小片段。但它让我觉得类型不匹配:
类型不匹配;发现:scala.concurrent.Future [Option [models.User]] => scala.concurrent.Future [Object] required: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))
}
}
你知道如何从这里继续前进吗?也许这甚至是错误的方法。 谢谢!
答案 0 :(得分: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))
}
}