【问题标题】:Reactivemongo and Play, chaining queriesReactivemongo 和 Play,链接查询
【发布时间】:2015-01-07 11:29:48
【问题描述】:

对 Scala(最新)、Reactivemongo(最新)和 Play 框架 (2.3.x) 有点陌生。

验证会话,并在成功时为其加载用户对象,并将其返回为 json。我猜问题是特定于映射和期货的。以下代码无法编译:

def userCheck(token: String) = Action.async {
  val futureSession = sessionCollection.find(Json.obj("token" -> token)).one[BSONDocument]

  futureSession.map {
    case Some(session) => {
      userCollection.find(Json.obj("_id" -> session.getAs[String]("userId").get )).one[JsObject].map {
        case Some(user) => Ok(JsObject(Seq("user" -> user)))
        case None => NotFound( JsObject(Seq("message" -> JsString("not found"))) )
      }
    }
    // NotFound( JsObject(Seq("message" -> JsString("not found"))) )
    case None => NotFound( JsObject(Seq("message" -> JsString("not found"))) )
  }
}

所以,错误信息是:

[error] AuthController.scala:186: overloaded method value async with alternatives:
[error]   [A](bodyParser: play.api.mvc.BodyParser[A])(block: play.api.mvc.Request[A] => scala.concurrent.Future[play.api.mvc.Result])play.api.mvc.Action[A] <and>
[error]   (block: play.api.mvc.Request[play.api.mvc.AnyContent] => scala.concurrent.Future[play.api.mvc.Result])play.api.mvc.Action[play.api.mvc.AnyContent] <and>
[error]   (block: => scala.concurrent.Future[play.api.mvc.Result])play.api.mvc.Action[play.api.mvc.AnyContent]
[error]  cannot be applied to (scala.concurrent.Future[Object])
[error]   def userCheck(token: String) = Action.async {

如果您查看源代码,您会看到一个注释行,如果我取消注释它,代码就会编译。我错过了一些案例吗?

更新 1:

因此,使用已接受答案中的提示,我想出了这个:

def userCheck(token: String) = Action.async {
  getSession(token).flatMap {
    session => {
      session match {
        case Some(s) => {
          getUser( s.getAs[String]("userId").get ).flatMap {
            user => {
              user match {
                case Some(u) => Future.successful( Ok( u ) )
                case None => Future.successful( NotFound( JsObject(Seq( "m" -> JsString("User not found")))))
              }
            }
          }
        }
        case None => Future.successful( NotFound( JsObject(Seq( "m" -> JsString("Session not found")))))
      }
    }
  }
}

def getSession(token: String): Future[Option[BSONDocument]] = {
  sessionCollection.find( Json.obj("token" -> token) ).one[BSONDocument]
}

def getUser(id: String): Future[Option[JsObject]] = {
  userCollection.find( BSONDocument( "_id" -> BSONObjectID(id) ) ).one[JsObject]
}

...它可以解决问题。不过感觉需要重构。

【问题讨论】:

    标签: scala playframework future reactivemongo


    【解决方案1】:

    尝试向所有分支添加显式类型;特别是,确保case Some(Session) 之后的块返回Result 或您认为应该是的任何内容。我怀疑在Some 分支中你最终会得到Future[Future[Result]] 而不是Future[Result] - 也许你需要做futureSession.flatMap,在None 的情况下返回Future.successful(...)

    【讨论】:

    • 我没有得到你提到的双重Future 嵌入式问题,但你的帖子让我找到了解决问题的正确方向。我已经用我的具体解决方案更新了我的帖子。其中一天我要去谷歌搜索“scala map vs flatmap with futures”。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2016-06-29
    • 1970-01-01
    相关资源
    最近更新 更多