在使用ReactiveMongo调用我的mongo实例时,我正在尝试进行理解。该方法应检查是否返回任何结果,如果不返回Future(NotFound)。但我收到一个我不明白的错误。
[info] Compiling 8 Scala sources and 1 Java source to /Users/Projects/reco_play/parser/target/scala-2.10/classes...
[error] /Users/Projects/reco_play/parser/app/controllers/Application.scala:94: value map is not a member of Object
[error] }.getOrElse(Future(NotFound))
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
进口:
import play.api.mvc._
import play.api.Play.current
import play.api.Logger
import play.modules.reactivemongo.{ReactiveMongoPlugin, MongoController}
import models.{Company}
import reactivemongo.api.collections.default.BSONCollection
import reactivemongo.bson.{BSONObjectID, BSONDocument}
import org.joda.time.DateTime
import scala.concurrent.{Future, ExecutionContext}
方式:
def showEditForm(id: String) = Action {
implicit request =>
implicit val reader = Company.CompanyReader
Async {
val objectId = new BSONObjectID(id)
val cursor = collection.find(BSONDocument("_id" -> objectId)).cursor[Company]
for {
maybeCompany <- cursor.headOption
result <- maybeCompany.map { company =>
Ok(views.html.editForm(Some(id), Company.form.fill(company)))
}.getOrElse(Future(NotFound))
} yield result
}
}
答案 0 :(得分:8)
好的,我更多地看了你的例子而你是对的,这是一个与我最初回答的问题不同的问题。首先,尝试将for-comp更改为:
for {
maybeCompany <- cursor.headOption
} yield {
maybeCompany.map{company =>
Ok(views.html.editForm(Some(id), Company.form.fill(company)))
}.getOrElse(NotFound)
}
您看到的问题与for-comp中的混合类型有关。您使用Future
启动了for-comp,然后尝试切换到Option
以进行下一步。这是for-comps的一个不幸的特征,因为你在第一行开始的任何类型都是你在整个理解过程中必须继续的相同类型。这是因为您不能flatMap
从Future[T]
到Option[T]
这是您在for-comp中会发生的事情。另一种方法是:
for {
maybeCompany <- cursor.headOption
result <- Promise.successful(maybeCompany.map { company =>
Ok(views.html.editForm(Some(id), Company.form.fill(company)))
}).future
} yield result.getOrElse(NotFound)
在这种方法中,在for-comp的第二步,我将Option
结果包装成一个成功完成的Future
,这是用于继续理解的正确类型。
答案 1 :(得分:0)
也许你可以尝试这样的事情。
for {
maybeCompany <- cursor.headOption
result <- maybeCompany.map { company =>
Promise.successful(
Ok(views.html.editForm(Some(id), Company.form.fill(company)))
).future
}.getOrElse(Future(NotFound))
} yield result