2013-11-14 2 views
1

При вставке значения в уровень сохранения и возвращении объекта результата обычно рекомендуется извлекать вновь созданный объект вместо повторного ввода входных данных.Вставка документа с повторной обработкой и извлечение его после этого

Когда я пытаюсь сделать это в 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 объект все в порядке.

Я думаю, что у меня есть общее недоразумение, что здесь происходит - возможно, есть лучший способ получить созданный объект за один выстрел.

ответ

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 в пределах урожая.

+0

спасибо много - это выглядит красиво, логично и работает! – DanielKhan

+0

Создание уникального идентификатора, который должен быть уникальным в какой-либо другой системе, - идея dab. Какова гарантия того, что этот createOID будет генерировать уникальную строку, которая будет уникальной в MongoDB? – sparkr