Scala для понимания Slick Query
Я новичок в 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, поэтому кажется, что это возможно.
1 ответ
Решение
Да, это возможно. Как это:
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
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
}
}