我有以下枚举类型。
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
我将枚举声明为类而不是对象,因为稍后我将需要类型信息(对于MappedColumnType)。
这是光滑表的非工作版本:
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)
}
我的目标是定义一个通用映射器函数来处理所有枚举,因为转换方法对所有类型的枚举都有效(值为id,id为value)。
在mapper函数中,我尝试捕获ClassTag信息并创建一个运行实例来调用apply方法,该方法返回枚举Value
。我必须在.asinstanceOf[V]
方法的结果中添加apply
,否则E#Value
的错误与V
的预期值不匹配。
现在,这是我得到的错误消息:
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")
我是scala的新手,我把一堆关于反射的食谱放在一起,想知道我是否在做一些根本错误的事情。
答案 0 :(得分:3)
您需要创建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)
)
然后你可以使用
// It convert Enum to Int
implicit val paymentMapper = enumIdMapper(Payment)
或者
// It convert Enum to String
implicit val paymentMapper = enumValueMapper(Payment)