0

I have a case class which is a model object in my application and goes like this:

case class MyModel(myTypeA: TypeA, str: String)
case class TypeA(intVal: Int, strVal: String)

I'm using MongoDB and the ReactiveMongo library for my persistence needs. I would like to convert this type to the BSONDocument so that I could persist this. I do not want to use the play reactive mongo module as I will be moving away from Play framework and use Spray at a later stage. I understand that I should write implicit conversions between BSON and my model types. As a starter, I have done the following:

implicit object MyModelBSONHandler extends BSONDocumentReader[MyModel] with BSONDocumentWriter[MyModel] {
  def read(doc: BSONDocument) = {
    MyModel(
      str = doc.getAs[String]("str").get,
      type = doc.getAs[TypeA]("myTypeA").get
    )
  }
  def write(myModel: MyModel) = {
    BSONDocument(
      "str" -> myModel.str,
      "myTypeA" -> myModel.myTypeA // Is this correct?
    )
  }
}

implicit object TypeABSONHandler extends BSONDocumentReader[TypeA] with BSONDocumentWriter[TypeA] {
  def read(doc: BSONDocument) = {
    TypeA(
      doc.getAs[Int]("intVal").get,
      doc.getAs[String]("strVal").get
    )
  }
  def write(typeA: TypeA) = {
    BSONDocument(
      "intVal" -> typeA.intVal,
      "strVal" -> typeA.strVal
    )
  }
}

As it can be seen, I'm not sure on how to write complex BSON types? I'm yet to give this a try in my code base!

joesan
  • 13,963
  • 27
  • 95
  • 232

1 Answers1

3

Try to use implicit handler value in object companion via Macros. Its more simple and elegant way to do this. There are some complex handler examples in class docs.

import reactivemongo.bson.Macros

case class MyModel(myTypeA: TypeA, str: String)

object MyModel{
    implicit val handler = Macros.handler[MyModel]
}

case class TypeA(intVal: Int, strVal: String)

object TypeA{
    implicit val handler = Macros.handler[TypeA]
}

class class Foo(n: Int, model: MyModel, tpe: TypeA, date: Long,
                name: String/* and so on */ )

object Foo{
   //and simple handler in one line of code
   implicit val handler = Macros.handler[TypeA]
}

I use custom handlers where needed a very specific behavior, other cases are quite covered with macros.

MrRontgen
  • 132
  • 1
  • 6