Defining projection to map to nested case classes
scala, slick-2.0
Solution
Our solution to this problem is to place the foreign key id in the case class, and to then use a lazy val or a def (the latter possibly being backed by a cache) to retrieve the record using the key. This is assuming that your `PolicyHolder`s are stored in a separate table - if they're denormalized but you want to treat them as separate case classes then you can have the lazy val / def in `Policy` construct a new case class instead of retrieving the record using the foreign key.
class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig {
def address = column[String]("ADDRESS", O.PrimaryKey)
def policyHolderId = column[String]("POLICY_HOLDER_ID")
def created = column[RichDateTime]("CREATED")
def duration = column[String]("DURATION")
def * = (address, policyHolderId, created, duration) <> (Policy.apply, Policy.unapply)
}
case class Policy(address : Future[Address], policyHolderId : Future[String], created : RichDateTime, duration : RichDuration ) {
lazy val policyHolder = policyHolderId.map(id => PolicyHolderDAO.get(id))
}
We also used a common set of create/update/delete methods to account for the nesting, so that when a `Policy` is committed its inner `PolicyHolder` will also be committed; we used a `CommonDAO` class that extended `Table` and had the prototypes for the create/update/delete methods, and then all DAOs extended `CommonDAO` instead of `Table` and overrode create/update/delete as necessary.
Edit: To cut down on errors and reduce the amount of boilerplate we had to write, we used Slick's code generation tool - this way the CRUD operations could be automatically generated from the schema
Problem
I have these case classes: ``` case class PolicyHolder(id : String, firstName : String, lastName : String) case class Policy(address : Future[Address], policyHolder : Future[PolicyHolder], created : RichDateTime, duration : RichDuration ) ``` I then have a slick schema defined for Policy ``` class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig { def address = column[String]("ADDRESS", O.PrimaryKey) def policyHolder = foreignKey("POLICY_HOLDER_FK", address, TableQuery[PolicyHolderDAO])(_.id) def created = column[RichDateTime]("CREATED") def duration = column[String]("DURATION") def * = (address, policyHolder, created, duration) <> (Policy.apply, Policy.unapply) } ``` What is the best way for me to define this projection correctly to map the `policyHolder` field inside of my `Policy` case class from the foreign key value to an actual instance of the `PolicyHolder` case class.