How about this?
// type def for Metadata
object MetadataType{ // singleton wrapper, because type defs can't be toplevel
type MetaData = (Int,Long)
}
import MetadataType.Metadata
// unpack using pattern matching
class HasMetaData(metadata: Metadata) {
val (id,timestamp) = metadata
}
case class Client(metadata: MetaData, name: String) extends HasMetaData(metadata)
case class Order(metadata: MetaData, items: List[Int], clientId: Int) extends HasMetaData(metadata)
// alternative: even avoid constructor argument
trait HasMetaData {
def metadata: Metadata
lazy val (id,timestamp) = metadata // lazy to avoid init order probs
}
case class Client(metadata: MetaData, name: String) extends HasMetaData
case class Order(metadata: MetaData, items: List[Int], clientId: Int) extends HasMetaData
Then in Slick:
...
def * = ((id,timestamp), name) <> (Client.tupled, Client.unapply)
...
Not sure items: List[Int]
is for an Order
. If it is a foreign key of a separate association table it shouldn't be here. A Order Table class is meant for describing exactly one database table. If you want to assemble data from several tables, write it externally as a value of type (Order,List[Int]) instead. You can implement it using a join with a subsequent groupBy on the client side or two separate queries. At some point we would like to support such a groupBy in Slick, which actually returns a nested collection, but at the moment you have to write it on the client side.