0

環境: 遊ぼう! 2.2.3、ReactiveMongo 0.10.0-SNAPSHOT

ドキュメントのリスト (「プロジェクト」としましょう) と、フィールドに入力するモーダル ダイアログをポップアップするボタンを含むページがあるとします。[OK] ボタンを押すと、ページは JSON 本文を含むリクエストをバックエンドに送信します。

{
    name: "Awesome Project", 
    url: "https://github.com/ab/cd", 
    repository: "git@github.com/ab/cd.git", 
    script: "empty"
}

Actionバックエンドは、次のように定義された にリクエストをルーティングします。

  def projectsCollection: JSONCollection = db.collection[JSONCollection]("projects")

  def create = Action.async(parse.json) { request =>
    projectsCollection.insert(request.body) map {
      case LastError(true,_,_,_,Some(doc),_,_) =>  Created(JsObject(List(
        "result" -> JsString("OK") ,
        "doc" -> BSONFormats.toJSON(doc)
      )))
      case LastError(false, err, code, msg, _, _, _) => NotAcceptable(JsObject(List(
        "result" -> JsString("ERROR"),
        "error" -> JsString(err.getOrElse("unknown")),
        "code" -> JsNumber(code.getOrElse[Int](0)),
        "msg" -> JsString(msg.getOrElse("no messsage"))
      )))
    }
  }

LastErrorケース クラスには、要求応答本文で返されるパラメーターがありますがoriginalDocument: Option[BSONDocument]、期待したドキュメントではありません。塗りつぶされたドキュメント、BSONObjectIDまたは少なくとも_idそれ自体が必要です。

新しく作成されたドキュメントを取得しようとすると、すべてが にラップされているため、行き止まりになりましたFuture

タスクを実行するエレガントなコードを作成する方法は?

4

3 に答える 3

0

私はPlay、scala、およびreactivemongoを初めて使用するので、答えが醜い場合はお許しください。ただし、挿入を取得してから作業を開始しました:

def createUser = Action.async(parse.json) { request =>
/*
 * request.body is a JsValue.
 * There is an implicit Writes that turns this JsValue as a JsObject,
 * so you can call insert() with this JsValue.
 * (insert() takes a JsObject as parameter, or anything that can be
 * turned into a JsObject using a Writes.)
 */
val userResult = request.body.validate[User]
userResult.fold(
errors => {
    Future.successful(
    Result(
        header = ResponseHeader(400, Map(CONTENT_TYPE->"application/json")),
        body = Enumerator(Json.obj("status" ->"KO", "message" -> JsError.toFlatJson(errors)).toString.getBytes())
        ))
},
user => blocking{ 
  // `user` is an instance of the case class `models.User`
  val insertDate = new DateTime()
  val newUser = user.copy(created_at = Some(insertDate) )

  collection.insert(newUser).map { lastError => 
    Logger.debug(s"Successfully inserted with LastError: $lastError")
    val cursor = collection.find(newUser).cursor[User]

     // gather all the JsObjects in a list
val futureUsersList: Future[List[User]] = cursor.collect[List]()


// transform the list into a JsArray
val futureUsersJsonArray: Future[JsArray] = futureUsersList.map { persons =>
  Json.arr(persons)
}

// everything's ok! Let's reply with the array
val res = futureUsersJsonArray.map { persons =>

    Created(persons)
  } 
   Await.result(res, Duration(1000, MILLISECONDS))
}


}

) }

于 2014-10-24T01:20:05.907 に答える
0

私もこれは初めてですが、reactive-mongo 0.11 では、 WriteResult を優先して LastError 構造を削除しまし。WriteResult には originalDocument フィールドがありますが、残念ながら 'TODO' というコメントで None に設定されています。

作成されたドキュメントを返すために思いついたもの (_id フィールドを除く)、

  def promiseOfWriteResult[T](writeResult:Future[WriteResult])(value:T) = {
    val p = Promise[T]
    writeResult map {
      case ok if ok.ok   => p.success(value)
      case error         => p.failure(error.getCause)
    } recover { // !important
      case x : Throwable => p.failure(x)
    }
    p.future
  }

これは次のように使用されます。

promiseOfWriteResult(collection.insert(doc))(doc)
于 2015-08-25T19:16:11.920 に答える