Scala用于理解流畅的查询

Scala用于理解流畅的查询,scala,playframework,slick,playframework-2.4,Scala,Playframework,Slick,Playframework 2.4,我是Scala新手,我正在构建一个Play应用程序来学习Scala和Slick。应用程序有待办事项列表,每个列表都有项目。每个用户都有多个列表。我已经编写了一个控制器来获取JSON列表,JSON包含列表中的所有项目 def viewList(id: Long) = AuthenticatedAction.async { implicit request => val userId = request.user.toLong; db.run(todoLists.filte

我是Scala新手,我正在构建一个Play应用程序来学习Scala和Slick。应用程序有待办事项列表,每个列表都有项目。每个用户都有多个列表。我已经编写了一个控制器来获取JSON列表,JSON包含列表中的所有项目

  def viewList(id: Long) = AuthenticatedAction.async { implicit request =>
    val userId = request.user.toLong;
    db.run(todoLists.filter(listById(id, userId)).result.headOption).flatMap { list =>
      list match {
        case Some(_) => {
          val json = toJson(list).as[JsObject]
          // Fetch the items in this list and add them to the JSON response
          db.run(todoItems.filter(_.listId === id).sortBy(_.text).result).map { items => 
            Ok(json + ("items" -> toJson(items)))
          }
        }
        case None => Future.successful(NotFound)
      }
    }
  }

是否可以使用一个用于理解的函数来编写此函数?我有一个嵌套的flatMap+map调用,所以它似乎应该是可能的。

是的,它是可能的。像这样:

def viewList(id: Long) = AuthenticatedAction.async { implicit request =>
  val userId = request.user.toLong
  for {
    list <- db.run(todoLists.filter(listById(id, userId)).result.headOption)
    resp <- list.fold[Future[Result]](Future.successful(NotFound)) { _ =>
      val json = toJson(list).as[JsObject]
      // Fetch the items in this list and add them to the JSON response
      db.run(todoItems.filter(_.listId === id).sortBy(_.text).result).map { items => 
        Ok(json + ("items" -> toJson(items)))
      }
    }
  } yield resp 
}
def viewList(id:Long)=AuthenticatedAction.async{implicit request=>
val userId=request.user.toLong
为了{
列表
Ok(json+(“项”->toJson(项)))
}
}
}收益率
}
另一种变体:

  def viewList(id: Long) = AuthenticatedAction.async { implicit request =>
    val userId = request.user.toLong
    for {
      list <- db.run(todoLists.filter(listById(id, userId)).result.headOption)
      items <- db.run(todoItems.filter(_.listId === id).sortBy(_.text).result)
    } yield list match {
      case Some(_) => Ok(toJson(list).as[JsObject] + ("items" -> toJson(items)))
      case None => NotFound
    }
  }
def viewList(id:Long)=AuthenticatedAction.async{implicit request=>
val userId=request.user.toLong
为了{
列表(项目)
case None=>NotFound
}
}

对于map、flatMap、filter的每次调用都可以重写以便于理解,但您真的需要它吗?这可能会更详细,这是一个很好的问题-我是Scala新手,所以我真的不知道。有人告诉我,理解可以使事情更容易阅读。如果你理解高阶函数的代码,我想你不会。也许只是为了练习,或者为了让别人更好地理解,我感谢你的回答。我不明白为什么不需要第一次调用
db.run
。另外,是否可以在理解中包含对map的其余调用?我试图将您重写的函数添加到我的代码中,但我得到一个编译错误:Controller.scala:79:type mismatch;找到[error]play.api.mvc.Result[error]required:TodoListController.this.Status[error]Ok(json+(“items”->toJson(items)))噢,很抱歉,您需要db.run。我添加了对
db.run
的调用,但仍然得到类型不匹配的编译错误。完整的编译错误在上面的注释中。第79行是带有
Ok
的行。我不明白为什么要求的类型是Status now。我意识到隔离调试可能很困难。我的完整项目位于:[未来[结果]]是必需的。此外,我还添加了另一个变体,例如。