Question

Here below is again the case class I presented in my previous post... but with the fix suggested by cmbaxter:

case class User(
  id: Option[BSONObjectID],
  name: String,
  addresses: Option[List[BSONObjectID]]
)

object User {
  implicit object UserWriter extends BSONDocumentWriter[User] {
    def write(user: User) = BSONDocument(
      "_id" -> user.id.getOrElse(BSONObjectID.generate),
      "name" -> user.name,
      "addresses" -> user.addresses
    ) 
  }

  implicit object UserReader extends BSONDocumentReader[User] {
    def read(doc: BSONDocument) = User(
      doc.getAs[BSONObjectID]("_id"),
      doc.getAs[String]("name").get,
      doc.getAs[List[BSONObjectID]]("addresses")
    )
  }
}

Now I'm trying to implement a Play controller that validates incoming Json and saves it into the database (MongoDB). Here below is my code:

object Users extends Controller with MongoController {

  private def collection = db.collection[JSONCollection]("users")

  def create = Action.async(parse.json) { request =>
    request.body.validate[User].map { user =>
      collection.insert(user).map { lastError =>
        Logger.debug(s"Successfully inserted with LastError: $lastError")
        Created
      }
    }.getOrElse(Future.successful(BadRequest("invalid json")))
  }
}

The code above does not compile because the compiler doesn't find any Json deserializer:

[error] /home/j3d/Projects/test/app/controllers/Users.scala:44: No Json deserializer found for type models.User. Try to implement an implicit Reads or Format for this type.
[error]     request.body.validate[User].map { user =>
[error]                          ^

Would it be possible to reuse the BSONDocumentWriter and BSONDocumentReader I've defined in the User companion object instead of implementing the Reads and Writes?

Was it helpful?

Solution

No, you can't reuse the BSON document reader/writers as JSON read/writes. However, you can reuse JSON read/writes as BSON document readers/writers. You want to use a JSONCollection to access the database from the play-reactive-mongo-plugin, then rewrite your BSON document reader/writers to be JSON reads/writes. You can see an example of doing this in the play-mongo-knockout activator template:

https://github.com/typesafehub/play-mongo-knockout

OTHER TIPS

if you are still looking for more complex example i just end up after 3 hours with this. It is basic implementation of automatic writes for models , it is validating json requests and storing to collection with 10 lines of code :) You dont need to repeat inserts in controller

https://github.com/MilosMosovsky/play-reactivemongo-models

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top