1

永続レイヤーに値を挿入して結果オブジェクトを返す場合、通常は、入力データを再度返すのではなく、新しく作成されたエンティティをフェッチすることをお勧めします。

Reactivemongo を使用して Scala でこれを実行しようとすると、自分の言語スキルにつまずきます。

def create(user: User): Future[User] = {
val newUser = user.createOID()

collection.insert(newUser).map {

  case ok if ok.ok => {
    for {
      createdUser <- this.findOne(BSONDocument("_id" -> newUser._id))
    } yield {

      createdUser match {
        case None => throw new RuntimeException("Could not find just created user")
        case Some(x) => x
      }
    }
  }
  case error => throw new RuntimeException(error.message)
  }
}

findOne の署名は次のとおりです。

def findOne(query: BSONDocument): Future[Option[User]]

次のエラーが表示されます。

[error]  found   : scala.concurrent.Future[models.User]
[error]  required: models.User
[error]  createdUser <- this.findOne(BSONDocument("_id" -> newUser._id))
[error]              ^

newUser オブジェクトを返せば問題ありません。

ここで何が起こっているのかを一般的に誤解していると思います-作成されたオブジェクトを一度に取得するより良い方法があるかもしれません。

4

1 に答える 1

1

それを行うための慣用的な Play/Scala の方法は次のとおりです。

def create(user: User): Future[Option[User]] = {
  val newUser = user.createOID()
  for {
    nu <- collection.insert(newUser)
    createdUser <- findOne(BSONDocument("_id" -> newUser._id))
  } yield {
    createdUser
  }
}

これは、コードFuture[Option[User]]とは異なり、返されることに注意してください。この場合、挿入が成功することが保証されていないことを実際にこのメソッドのクライアントに伝えるため、これが間違いなく正しい方法だと思います(したがって、クライアントがこのメソッドの結果に対して行うようにランタイム例外は必要ありませんFuture[User]—例外の使用を避けますあなたがそれらに優雅に対処できれば)。Option[User].map

歩留まりの範囲内であることを確認nuすることもできます。ok

于 2013-11-14T15:13:21.393 に答える