Reputation: 458
I have this fucntion:
def updateInvoiceAdminStatusField(id: Int, newAdminStatus: AdminStatus): Future[Int] = {
db.run {
val adminStatus: Query[Rep[AdminStatus], AdminStatus, Seq] = InvoicesTable.filter(invoice => invoice.id === id).map(invoice => invoice.status)
adminStatus.update(newAdminStatus)
}
}
I thought of making it generic:
def updateInvoiceField[T](id: Int, fieldExtractor: (Invoices) => Rep[T], newValue: T): Future[Int] = {
db.run {
val adminStatus = InvoicesTable.filter(invoice => invoice.id === id).map(invoice => {
fieldExtractor(invoice)
})
adminStatus.update(newValue)
}
}
But this does not compile. Can somebody assist?
Upvotes: 4
Views: 211
Reputation: 2476
It's nearly good. With small changes like below it should work:
// I added below T: ColumnType
def updateInvoiceField[T: ColumnType](id: Int, fieldExtractor: (Invoices) => Rep[T], newValue: T): Future[Int] = {
db.run {
val adminStatus = InvoicesTable.filter(invoice => invoice.id === id).map(invoice => {
fieldExtractor(invoice)
})
adminStatus.update(newValue)
}
}
Notice I added this : ColumnType
which basically mean you need to have proper implicit in scope - specifically the one that would convert T
=> ColumnType[T]
. That's simply because otherwise T
could be anything and Slick
wouldn't be able to figure out how to convert it.
So for things like String
, Int
etc. you obviously have proper conversations already in place (imported from api
in profile/driver). For you custom types you would need to use MappedColumnType
to have proper conversion supplied. Example below (typesafe ID):
implicit def columnType[T]: BaseColumnType[Id[T]] =
MappedColumnType.base[Id[T], Long](toLong, fromLong)
private def fromLong[T](dbId: Long): Id[T] = Id(dbId)
private def toLong[T](id: Id[T]): Long = id.value
Upvotes: 3