Search code examples
scalaslick

Slick - one to many table schema


Suppose I have case classes as follows:

case class Warehouse(name:String, products:Seq[Product])
case class Product(name:String)

I would like to define a table which is bound to the Warehouse type

class Warehouses(tag: Tag) extends Table[Warehouse](tag, "warehouses") {
      def id = column[UUID]("id", O.PrimaryKey)
      def name = column[String]("name")
      def products = ???
}

I could define my table with tuples and reference Warehouses from Products - that would be one-to-many relationship I need. However I need my Tables to reflect my domain classes so I can execute DBIO actions and get Warehouse not a tuple:

val warehouses = TableQuery[Warehouses]
db.run(warehouses.filter(_.id === 2).result.head) //this is of type Warehouse

How can I define a schema from the case class which contains a collection?


Solution

  • Slick is not ORM

    So, Slick does not support nested objects like hibernate. If you strongly want to have nested objects model Slick is not a suitable solution for your use case. This point is explicitly mentioned in the slick documentation as well.

    Your use case in Slick is modelled like this

    case class WarehouseModel(name:String, id: Long)
    case class ProductModel(name:String, productId: Long)
    case class WarehouseProductsModel(warehouseId: Long, productId: Long) 
    

    WarehouseProductsModel captures the one-many relationship between Product and Warehouse

    Note that above design looks like the typical database design one would choose to do in case of one-many relationship. In Slick these models represents relational tables. So, for each table we need to have one model which represents that table in code. Slick helps in writing sql agnostic, composable, reusable, typesafe and scala collection like queries. So end of the day Slick code looks like Scala collections manipulation code.