在我的Play2应用程序中使用Future进行getOrElse时,获取值映射不是Object的成员

时间:2013-05-02 18:51:27

标签: mongodb scala playframework playframework-2.1

在使用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
      }
  }

2 个答案:

答案 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的一个不幸的特征,因为你在第一行开始的任何类型都是你在整个理解过程中必须继续的相同类型。这是因为您不能flatMapFuture[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