kclay / rethink-scala

Scala Driver for RethinkDB
Other
100 stars 24 forks source link

Support class polymorphism #23

Closed dainkaplan closed 9 years ago

dainkaplan commented 9 years ago

It would be nice to have an easy way to use class polymorphism in collection fields within documents, e.g. List[Bug] containing Spider and Worm, even if custom serialisers are needed to accomplish it. Looks like this should be doable since you're using Jackson to do the JS serialisation. Glanced at the serialisation code but it wasn't readily apparent (lots of commented out code / unused stuff). I will gladly create a test case that does this if you could provide some pointers!

kclay commented 9 years ago

Think you should be able to follow somethin like this http://stackoverflow.com/questions/21485923/java-jackson-polymorphic-json-deserialization-of-an-object-with-an-interface-pr

It does muck up the json stored in rethinkdb, so if accessing from other api's it would need to be removed.

dainkaplan commented 9 years ago

This appears to be trumped by not being able to create a collection of non-primatives within a document, i.e.:

case class Bug(name: String)
case class Terrarium(bugs: List[Bug]) extends Document

bugs above cannot be a case class in the current implementation. (Without this, there isn't much point in sorting out polymorphic de/serialisation.) @kclay Is this something you could add?

kclay commented 9 years ago

I havn't tested this out yet but in the 0.4.7-SNAPSHOT I addressed the problem of classes not extending Document having their values set to null #19.

@dainkaplan If you could give that a try and let me know if that works for you.

kclay commented 9 years ago

Got around to testing this and I see what you mean now, I'll work on it

kclay commented 9 years ago

@dainkaplan updated the snapshot to work with jackson a bit better.

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
trait NestedAddress

case class NestedAddress1(street:NestedStreet)       extends NestedAddress

case class NestedAddress2(name:String)  extends NestedAddress

case class NestedUser(name: String, active: Boolean , address:List[NestedAddress], id: Option[String] = None)

This will add an field named "@className" which will be used later for deserialization. This property can be configured via configuring the annotations.

vmarquez commented 9 years ago

@kclay I see that this is working now, however the test case didn't seem to be working that shows this feature (though it passed the test, it was returning a None).

I came up with a test in my own branch that more or less mirrors how SelectTest works with the NestedUser object to show that this functionality does in fact properly serialize polymorphic values inside generic collections. https://github.com/vmarquez/rethink-scala/blob/nested_test/core/src/test/scala/com/rethinkscala/NestedTest.scala

kclay commented 9 years ago

Perfect, you can go ahead and do a pull request if you like