I am using SLICK 1.0.0-RC2. I have defined the following two tables Directorate and ServiceArea where Directorate has a one to many relationship with ServiceArea
case class Directorate(dirCode: String, name: String)
object Directorates extends Table[Directorate]("DIRECTORATES") {
  def dirCode = column[String]("DIRECTORATE_CODE", O.PrimaryKey)
  def name = column[String]("NAME")
  def * = dirCode ~ name  <> (Directorate, Directorate.unapply _) 
}
case class ServiceArea(areaCode: String, dirCode: String, name: String)
object ServiceAreas extends Table[ServiceArea]("SERVICE_AREAS") {
  def areaCode = column[String]("AREAE_CODE", O.PrimaryKey)
  def dirCode = column[String]("DIRECTORATE_CODE")
  def name = column[String]("NAME")
  def directorate = foreignKey("DIR_FK", dirCode, Directorates)(_.dirCode)
  def * = areaCode ~ dirCode ~ name <> (ServiceArea, ServiceArea.unapply _)
}
To make the Directorate case class useful in my Play application form I am trying to redefine the Directorate case class to have a Seq of ServiceAreas that are related to that Directorate.
case class Directorate(dirCode: String, name: String, serviceAreas: Seq[ServiceArea])
My problem is now with the Directorate table projection. I have attempted to create a method in Directorates:
def serviceAreas = (for { a <- ServiceAreas
                         if (a.dirCode === dirCode)
                    } yield (a)).list map {
                      case t: ServiceArea => t
                    }
so that I can try something like
def * = dirCode ~ name  ~ serviceAreas <> (Directorate, Directorate.unapply _)
but this cannot not work as serviceAreas only goes one way.
It seems reasonable to me that for the Directorate case class to be a useful domain object that it should be able contain the related ServiceAreas.
I'm wondering how I should traverse the inverse relationship so that Directorate table projection will work.
I'm sure there is a more elegant solution, but this should do the trick:
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
object SlickExperiments2 {
  Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
    (Directorates.ddl ++ ServiceAreas.ddl).create
    case class Directorate(dirCode: String, name: String) {
      def serviceAreas: Seq[ServiceArea] = (for {
        a <- ServiceAreas
        if (a.dirCode === dirCode)
      } yield (a)).list
    }
    object Directorates extends Table[Directorate]("DIRECTORATES") {
      def dirCode = column[String]("DIRECTORATE_CODE", O.PrimaryKey)
      def name = column[String]("NAME")
      def * = dirCode ~ name <> (Directorate, Directorate.unapply _)
    }
    case class ServiceArea(areaCode: String, dirCode: String, name: String)
    object ServiceAreas extends Table[ServiceArea]("SERVICE_AREAS") {
      def areaCode = column[String]("AREAE_CODE", O.PrimaryKey)
      def dirCode = column[String]("DIRECTORATE_CODE")
      def name = column[String]("NAME")
      def directorate = foreignKey("DIR_FK", dirCode, Directorates)(_.dirCode)
      def * = areaCode ~ dirCode ~ name <> (ServiceArea, ServiceArea.unapply _)
    }
    Directorates.insert(Directorate("Dircode", "Dirname"))
    ServiceAreas.insertAll(ServiceArea("a", "Dircode", "A"), ServiceArea("b", "Dircode", "B"))
    val sa = (for{
    d <- Directorates
    } yield d).list map { case t: Directorate => t.serviceAreas}
    println(sa)
  }                                              
 //> List(List(ServiceArea(a,Dircode,A), ServiceArea(b,Dircode,B)))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With