玩框架/依赖未来组成

时间:2015-06-02 20:18:29

标签: scala playframework slick play-slick

我正在尝试进行几次相关的Slick / DB调用,然后在旋转模板中显示结果数据。

def show(slug: String) = Action.async { implicit rs =>

    for {

      f <- fooDAO.findBySlug(slug)  // f is of type Option[foo]
      fid <- f.flatMap(a => a.id.map(b => b)) // fid is of type Long
      b <- barDAO.findByFooId(fid) // b is of type Seq[bar] 

    } yield {

        f.map {
          case Some(f) => Ok(views.html.foobar(f, b))
          case _ => NotFound
        }

      }
  }

我首先需要获得&#34; ID&#34;然后能够查询其他相关数据。编译器现在产生此错误:

play.sbt.PlayExceptions$CompilationException: Compilation error[type mismatch;
 found   : scala.concurrent.Future[Option[play.api.mvc.Result]]
 required: Option[?]]

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

您的代码存在一个根本性缺陷,因为您在同一理解中混合Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) Option

预计for-comprehension将在同一个&#34;容器&#34; type,它将是Seq

的结果表示形式

e.g。如果您合并多个yield,则会获得Option,如果合并Option,则会获得Seq

在这种情况下,您可以通过将Seq(foo)转换为Option来解决此问题(如果foo为Seq则为空,如果不是,则为1)

最终结果将是

None

但我猜这不是你需要的。我想您希望获取与检索到的val results: Seq[(Foo, Bar)] = for { f <- fooDAO.findBySlug(slug).toSeq // f is of type Seq[Foo] b <- barDAO.findByFooId(f.id) // b is of type Seq[Bar] } yield (f, b) 相关联的所有Bar(如果有),并将其与您的模板一起展示。如果Foo没有Foo,则需要slug

我们可以这样做

NotFound

您可以通过定义支持方法

来使其更明确
def show(slug: String) = Action.async { implicit rs =>

  val f = fooDAO.findBySlug(slug)  // f is of type Option[Foo]

  f.fold(
    NotFound,
    foo => Ok(views.html.foobar(foo, barDAO.findByFooId(foo.id))
  )

}

答案 1 :(得分:0)

理解你在这里想要达到的目标有点棘手,但是如果整个事情都是基于findbySlug返回Future[Option[Foo]],最终结果为NotFound OptionNone,那么您的yield应该只是:{/ p>

   ...
 } yield {
  f.fold(NotFound)(foo => Ok(views.html.foobar(foo, b)))
}

Option[T]是数据检索和控制流的理想类型,但是pattern-matching on it is almost never the right approachfold的使用对于任务非常简洁。