In a Play application, I have a few tables and classes that share the same structure. I want to keep them different to maintain application semantics (yay static typing!). However, I'd like to avoid duplicating boilerplate code.
For example, here's class Region
.
case class Region(id: Int, name:String)
and here is its Slick's table query class:
class RegionsTable(tag:Tag) extends Table[Region](tag, "regions") {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def name = column[String]("name", O.Unique)
def * = (id, name) <> (Region.tupled, Region.unapply)
}
How can I avoid duplicating the table query class for each of the other classes that share Region
's structure?
Perhaps not very Slick native solution, but refactoring might look like:
import slick.jdbc.H2Profile.api._
import scala.reflect.ClassTag
case class Region(id: Int, name: String)
case class Country(id: Int, name: String)
class IdNameTable[T](tag: Tag, tableName: String, apply: (Int, String) => T, unapply: T => Option[(Int, String)])
(implicit classTag: ClassTag[T]) extends Table[T](tag, tableName) {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def name = column[String]("name", O.Unique)
def * = (id, name) <> (apply.tupled, unapply)
}
class RegionsTable(tag: Tag) extends IdNameTable[Region](tag, "regions", Region, Region.unapply)
class CountryTable(tag: Tag) extends IdNameTable[Country](tag, "country", Country, Country.unapply)
Working Scatie example: https://scastie.scala-lang.org/fR7BzS1jSKSXptE9CTxXyA