Search code examples
scalamongodbcasbah

How to convert a scala object with list to a MongoDBObject via Casbah


I'm learning MongoDB and Casbah by writing a simple app. Got stuck when I try to convert an object with a list member into a MongoDB Object. Here is my class

case class BorrowerRecord( name: String, checkedOut: List[BookTag]) {
  require(!name.isEmpty)
  require(!checkedOut.isEmpty)
}

case class BookTag (subject: Subject, bookName: String) {
  require(!bookName.isEmpty)
}

case class Subject (name: String, category: Category) {
  require(!name.isEmpty)  
}  

Category is a sealed trait with 2 case class implementation, I intended to use this like "Enum"

sealed trait Category {
  def name: String
}

object Category {
  case object Computing extends Category { val name = "Computing"}
  case object Math extends Category { val name = "Math"}
}

So, a instance of BorrowerRecord will keep what books a person checked out from the library, each book is identified by a BookTag object. A BookTag keeps some information about a book like bookname, subject name, Category, etc.

Lets say I've a BorrowerRecord and want to save it to MongoDB

val borrowOnToday = BorrowerRecord( "My Name", List( BookTag(Subject("J2EE", Category.Computing), "Head First Java"), 
                                                     BookTag(Subject("Linear Algebra", Category.Math), "Algebra for Dummies")))

How should I convert this to MongoDBObject using Casbah ?

Or Casbah is not the way to go and there're other libraries that can help me persist this into MongoDB more easily?


Solution

  • To work with case classes use the salat (press <- and -> to move through the presentation).

    It is pretty simple:

    case class Alpha(x: String)
    
    scala> val a = Alpha(x = "Hello world")
    a: com.novus.salat.test.model.Alpha = Alpha(Hello world)
    
    scala> val dbo = grater[Alpha].asDBObject(a)
    dbo: com.mongodb.casbah.Imports.DBObject = { "_typeHint" : 
        "com.novus.salat.test.model.Alpha" , "x" : "Hello world"}
    
    scala> val a_* = grater[Alpha].asObject(dbo)
    a_*: com.novus.salat.test.model.Alpha = Alpha(Hello world)
    

    Usually, I'm using them both: casbah to querying to/from Mongo, and salat to make a conversions to case classes and vice versa.

    And yes, salat supports case classes with Lists (here is the list of supported collections).