Reactivemongo 和 Play,链接查询
Reactivemongo and Play, chaining queries
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]
}
...它成功了。不过感觉需要重构。
尝试向所有分支添加显式类型;特别是,确保 case Some(Session)
return 之后的块是 Result
或您认为应该是的任何内容。我怀疑在 Some
分支中你得到的是 Future[Future[Result]]
而不是 Future[Result]
- 也许你需要做 futureSession.flatMap
,而在 None
案例 return Future.successful(...)
.
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]
}
...它成功了。不过感觉需要重构。
尝试向所有分支添加显式类型;特别是,确保 case Some(Session)
return 之后的块是 Result
或您认为应该是的任何内容。我怀疑在 Some
分支中你得到的是 Future[Future[Result]]
而不是 Future[Result]
- 也许你需要做 futureSession.flatMap
,而在 None
案例 return Future.successful(...)
.