scala - Slick and nesting case classes a no go? -
i using slick (and play framework) build application on top of existing database. cannot change database structure.
my database has following 2 tables:
meeting:
- id (pk)
- name
- chairman_id (fk person.id)
- houseman_id (fk person.id)
person:
- id (pk)
- first_name
- last_name
i wanted define case classes this:
case class meeting ( id: int, name: string, chairman: person, houseman: person ) case class person ( id: int, firstname: string, lastname: string ) but minimal slick documentation around this, looks have keep ids in case class rather using "person". correct?
whats best approach this? sorry relatively open question, new scala, slick , play.
thanks,
ed
you have foreign keys, don't translate case classes, translate ids:
case class meeting ( id: int, name: string, chairmanid: int, housemanid: int) case class person ( id: int, firstname: string, lastname: string) and schema like:
case class meeting ( id: int, name: string, chairmanid: int, housemanid: int) case class person ( id: int, firstname: string, lastname: string) class meetings(tag: tag) extends table[meeting](tag, "meeting") { def * = (id, name, chairmanid, housemanid) <>(meeting.tupled, meeting.unapply) def ? = (id.?, name, chairmanid, housemanid).shaped.<>({ r => import r._ _1.map(_ => meeting.tupled((_1.get, _2, _3, _4))) }, (_: any) => throw new exception("inserting ? projection not supported.")) val id: column[int] = column[int]("id", o.autoinc, o.primarykey) val name: column[string] = column[string]("name") val chairmanid: column[int] = column[int]("chairmanid") val housemanid: column[int] = column[int]("housemanid") lazy val meetingchairmanfk = foreignkey("meeting_chairman_fk", chairmanid, persons)(r => r.id, onupdate = foreignkeyaction.restrict, ondelete = foreignkeyaction.cascade) lazy val meetinghousemanfk = foreignkey("meeting_houseman_fk", housemanid, persons)(r => r.id, onupdate = foreignkeyaction.restrict, ondelete = foreignkeyaction.cascade) } lazy val meetings = new tablequery(tag => new meetings(tag)) class persons(tag: tag) extends table[person](tag, "person") { def * = (id, firstname, lastname) <>(person.tupled, person.unapply) def ? = (id.?, firstname, lastname).shaped.<>({ r => import r._ _1.map(_ => person.tupled((_1.get, _2, _3))) }, (_: any) => throw new exception("inserting ? projection not supported.")) val id: column[int] = column[int]("id", o.autoinc, o.primarykey) val firstname: column[string] = column[string]("firstname") val lastname: column[string] = column[string]("lastname") } lazy val persons = new tablequery(tag => new persons(tag)) and used this:
val thismeeting = meetings.filter(_.name === "thismeeting").join(persons).on((m, p) => m.housemanid === p.id || m.chairmanid === p.id).list() or using comprehension (which find more legible):
val thatmeething = (for { m <- meetings p <- persons if (p.id === m.chairmanid || p.id === m.housemanid) && m.name === "thatmeeting" } yield m.id).run note second query corresponds implicit inner join, other types of join supported, can find them here.
Comments
Post a Comment