After hours trying to get MongoCaseClassListField
working, I think I got pretty close. I even got a type hint in my output JSON in the REPL. But I can't seem to get my Record classes to see the format definitions when I need them to.
scala> import bootstrap.liftweb._
scala> import com.mypackage.model._
scala> import net.liftweb.json._
scala> import net.liftweb.json.JsonDSL._
scala> import net.liftweb.json.JsonAST
scala> new Boot().boot
scala> val jobject1 = ("vid" -> "aaa") ~ ("title" -> "bbb") ~ ("description" -> "ccc") ~ ("time" -> 1234)
rv1: net.liftweb.json.JsonAST.JObject = JObject(List(JField(vid,JString(aaa)), JField(title,JString(bbb)), JField(description,JString(ccc)), JField(time,JInt(1234))))
scala> val videoitem1 = VideoItem.create(jobject1)(MediaLibrary.formats)
vi1: com.mypackage.model.VideoItem = VideoItem(aaa,bbb,ccc,1234.0,List())
scala> val ml = MediaLibrary.createRecord.libraryName("Test3").libraryItems(videoitem1 :: Nil) # NOTE: No JsonClass field !!!
mi1: com.mypackage.model.MediaLibrary = class com.mypackage.model.MediaLibrary={libraryItems=List(VideoItem(aaa,bbb,ccc,1234.0,List())), _id=53278cb7ccf2ebe412398548, libraryName=Test3}
scala> ml.save
res1: com.mypackage.model.MediaLibrary = class com.mypackage.model.MediaLibrary={libraryItems=List(VideoItem(aaa,bbb,ccc,1234.0,List())), _id=53278cb7ccf2ebe412398548, libraryName=Test3}
This refers to the following code:
trait LibraryItem
case class VideoItem (
vid: String,
title: String,
description: String,
time: Double,
tags: Seq[String]) extends LibraryItem with JsonObject[VideoItem] {
def meta = VideoItem
}
object VideoItem extends JsonObjectMeta[VideoItem]
case class LinkItem (
url: String,
title: String,
tags: Seq[String]) extends LibraryItem with JsonObject[LinkItem] {
def meta = LinkItem
}
object LinkItem extends JsonObjectMeta[LinkItem]
class MediaLibrary extends MongoRecord[MediaLibrary] with ObjectIdPk[MediaLibrary] {
def meta = MediaLibrary
object libraryName extends StringField(this, 256)
object libraryItems extends MongoCaseClassListField[MediaLibrary, LibraryItem](this)
}
object MediaLibrary extends MediaLibrary with MongoMetaRecord[MediaLibrary] {
override def formats = Serialization.formats(ShortTypeHints(List(classOf[VideoItem], classOf[LinkItem])))
}
I can write a record to Mongo, but there's never a type hint. And I can get a record back, but it will always return a an empty list for the libraryItems.
There have been many, many variations of this code during the day. But I no longer know in which directions to go.
Ideally, of course, what I'd want is to create a MediaLibrary
whose items are either VideoItem
s or LinkItem
s. When querying the database, I'd like a list of LibraryItem
s that I could pattern-match to the two case classes, or maybe even a list of instances of the two case classes. I must be missing something, but what?
formats
was defined in the wrong place!
This works:
class MediaLibrary extends MongoRecord[MediaLibrary] with ObjectIdPk[MediaLibrary] {
def meta = MediaLibrary
object libraryName extends StringField(this, 256)
object libraryItems extends MongoCaseClassListField[MediaLibrary, LibraryItem](this){
override def formats = Serialization.formats(ShortTypeHints(List(classOf[VideoItem], classOf[LinkItem])))
}
}
object MediaLibrary extends MediaLibrary with MongoMetaRecord[MediaLibrary]