3

当我用 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
      }
  }
4

2 回答 2

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 中的混合类型有关。您以 a 开始 for-comp,Future然后尝试切换到 aOption进行下一步。这是 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内容中,这是用于继续理解的正确类型。

于 2013-05-02T20:08:54.843 回答
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
于 2013-05-03T14:53:24.247 回答