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
    }
  }
Другие вопросы по тегам