Search code examples
scalaslick

Slick many-to-one mappings


I have 3 tables, which are defined as 3 case classes. Seller and Buyer both has a one to many relationship with Address. Is there way that I can use one foreign key in the Address table to point to both Seller and Buyer table, instead of using two foreign keys? I am not sure how to write the mappings. Here is what I got:

case class Seller(id: Long, name: String)
case class Buyer(id: Long, name: String)
case class Address(id: Long, street: String, city: String, userId: Long)

class SellerTableDef(tag: Tag) extends Table[Seller](tag, "seller") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  override def * = (id, name) <> (Seller.tupled, Seller.unapply)
}

class BuyerTableDef(tag: Tag) extends Table[Seller](tag, "buyer") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  override def * = (id, name) <> (Buyer.tupled, Buyer.unapply)
}

class AddressTableDef(tag: Tag) extends Table[Address](tag, "address") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def street = column[String]("street")
  def city = column[String]("city")
  def userId = column[Long]("user_id")

  //!!!Can I use one foreign key to point to both the Seller and the Buyer table?!!! 
  def user = foreignKey("user_FK", userId, ???)(_.id)
}

Many thanks.


Solution

  • this seems more of a DB design question.

    The common practice is to have a Buyer table, a Seller table, an Address table. And then each Buyer/Seller row has a addressID FK. The address table shouldn't have a Buyer/Seller id because the address may belong to several rows

    Edit after comment:

    in that case, you need a BuyerAddress (same for SellerAddress) table, with a buyerId and addressId, which will keep all the addresses for each buyer (buyerId, addressId)

    BuyerTable: id, name SellerTable: id, name AddressTable: id, street, city, userId BuyerAddressTable: buyerId, addressId SellerAddressTable: sellerId, addressId