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.

Original source