Reputation: 1116
I have following enumeration types.
class Payment extends Enumeration {
type Payment = Value
val Cash, CreditCard, Unspecified = Value
}
object Payment extends Payment
class Ticket extends Enumeration {
type Ticket = Value
val Normal, Discount, Other = Value
}
object Ticket extends Ticket
I declared enumerations as classes instead of objects as i will need the type information later (for MappedColumnType).
Here is the non working version of the slick table:
class Stats(tag: Tag) extends Table[Stat](tag, "STATS") {
implicit def enumToInt[E <: Enumeration : ClassTag, V : ClassTag](implicit conv: V => E#Value): BaseColumnType[V] =
MappedColumnType.base[V, Int] (
value => value.id,
num => implicitly[ClassTag[E]].runtimeClass.newInstance().asInstanceOf[E](num).asInstanceOf[V]
)
def entityid = column[Int]("ENTITYID")
def email = column[String]("EMAIL")
def payment = column[Payment]("PAYMENT")
def ticket = column[Ticket]("TICKET")
def phone = column[String]("PHONE")
def ticket_source = column[TicketSource]("TICKETSOURCE")
def * = (entityid, email, payment, ticket, phone, ticket_source) <>
(Stat.tupled, Stat.unapply)
}
My goal is defining a generic mapper function to handle all of enumeration as the conversion methods are valid for all type of enumerations (value to id, id to value).
In mapper function i tried to capture ClassTag information and create a running instance to call the apply method which returns a enumeration Value
. I had to add .asinstanceOf[V]
to the result of apply
method, otherwise error is risen about E#Value
does not match with expected value of V
.
Now, this what i get as an error message:
Tables.scala:45: could not find implicit value for parameter tm: scala.slick.ast.TypedType[com.yokyer.tiyatrosever.models.Payment]
[error] def payment = column[Payment]("PAYMENT")
[error] ^
Tables.scala:46: could not find implicit value for parameter tm: scala.slick.ast.TypedType[com.yokyer.tiyatrosever.models.Ticket]
[error] def ticket = column[Ticket]("TICKET")
I am new to scala, i put bunch of recipes about reflections put together and wondering if i am doing something fundamentally wrong.
Upvotes: 2
Views: 846
Reputation: 46
you need to create a MappedColumnType
import profile.simple._
def enumValueMapper(enum: Enumeration) = MappedColumnType.base[enum.Value, String](
e => e.toString,
s => Try(enum.withName(s)).getOrElse(throw new IllegalArgumentException
(s"enumeration $s doesn't exist $enum
[${enum.values.mkString(",")}]"))
)
def enumIdMapper(enum: Enumeration) = MappedColumnType.base[enum.Value, Int](
e => e.id,
i => enum.apply(i)
)
then you can use
// It convert Enum to Int
implicit val paymentMapper = enumIdMapper(Payment)
Or
// It convert Enum to String
implicit val paymentMapper = enumValueMapper(Payment)
Upvotes: 3