ALMEK ALMEK - 20 days ago 9
Scala Question

What are the way/s of telling scala compiler that type TableQuery[T] can map to somthing has the attribute id

I want the compiler to know or to test if, that type T having a property id.

def del[T](id: Int) = TableQuery[T] filter (_.id === id) delete

Answer

The other answers are somehow correct but I doubt they will work with Slick, your id has to be a Rep of some parameter and not an Int, the best way would be to have an abstract table with and id field and make your concrete table extend that:

abstract class RichTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
  val id: Rep[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc)
}

class ConcreteTable(tag: Tag) extends RichTable[ConcreteRow](tag, "concrete_table") { ... }

Note that I made the id primary key. Now any TableQuery[T] with [T <: RichTable[A], A] will have access to an id:

trait GenericPersistence[T <: RichTable[A], A] {

  val tableReference: TableQuery[T]

  def deleteById(id: Long)(implicit s: Session): Boolean = 
    tableReference.filter(_.id === id).delete == 1

  /* other generic methods ids based */
}

For a more complete answers with other methods you can have a look at this, for Slick 3 it's basically the same.

You can achieve the same result with a trait:

trait RichTable[T] {
  self: Table[T] =>

  val id: Rep[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc)
}

class ConcreteTable(tag: Tag) extends Table[ConcreteRow](tag, "concrete_table") with RichTable[ConcreteRow]

You can decide if you want to implement the id field in the trait or not.

Comments