2017-02-13 30 views
2

说我有像模特:我应该创建traits来表示我的模型的枚举值吗?

case class User(
id: Int, 
name: String, 
userType: Int) 

我应该那么做:

sealed trait UserType 
case object Member() extends UserType 
case object Anonymous() extends UserType 

我也莫名其妙的值对每个用户类型相关联。

我会然后更改用户案例类有一个UserType属性而不是int?

我想我会然后创建一个隐式的转换器,我相信这将是一个从int到UserType的MappedColumnType。

更新 这是用于使用光滑的数据库访问。

+0

重复此:http://stackoverflow.com/questions/28331528/scala-enumerations-case-objects-in-slick-good-ractices –

回答

2

我会以相反的方式做到这一点。在需要的时候

sealed trait User 
case class NormalUser(name: String, id: Int) extends User 
case class SuperUser(name: String, id: Int, superPowers: Map[String, String]) extends User 

然后模式匹配实际User类型:我会对取决于扩展User方案中的用户类型。

+0

对不起,但这是光滑的具体,我会强调超越光滑的标记。 – Blankman

2

我会去用枚举:

object UserType extends Enumeration { 
    type UserType = Value 

    val Member = Value("Member") 
    val Anonymous = Value("Anonymous") 
} 

和转换器,你说:

implicit val userTypeColumnType = MappedColumnType.base[UserType, String](
    userType => userType.toString, 
    UserType.withName 
) 

然后你就可以在你的User情况下,课堂上使用userType: UserType。 在表定义,你可以有def userType = column[UserType]("user_type")

更新 的原因之一,超过性状选择枚举是光滑是不是能找到这个隐含的转换器,当你不把超明确。 例如

.filter(_.userType === Member) 

产生

type mismatch; 
[error] found : Member.type 
[error] required: slick.lifted.Rep[?] 
[error]  .filter(_.userType === Member).result 

但接下来的工作

.filter(_.userType === Member.asInstanceOf[UserType]) 

.filter(_.userType === (Member : UserType)) 
1

由于@Michal Tomanski提到below - 使用trait/case object■当存在一定问题。什么,你需要做的是:

sealed trait UserType { 
    val code: Int 
    } 
    case object Member extends UserType { 
    override val code: Int = 0 
    } 
    case object Anonymous extends UserType { 
    override val code: Int = 1 
    } 

    object UserType { 
    def byId(id: Int): UserType = id match { 
     case Member.code => Member 
     case Anonymous.code => Anonymous 
     case _ => throw new IllegalArgumentException("...") 
    } 
    } 

    implicit val enumColumnType = MappedColumnType.base[UserType, Int](
    e => e.code, 
    i => UserType.byId(i) 
) 

上面会允许你做这样的查询:

UserTable 
     .filter(_.userType === (Member :: UserType)) 
     .result 

这正是@Michal Tomanski指出。你可以做一些小技巧来平滑一点。

只需修改您的特点是这样的:

sealed trait UserType { 
    val code: Int 
    // I added field below 
    val base: UserType = this 
    } 

,然后你可以有你这样的查询:

UserTable 
     .filter(_.userType === Member.base) 
     .result 

它可能会稍微更好的选择比铸造。

除此之外 - 我跟随@Michal Tomanski答案(使用Enumeration)假设就足够了你的情况(或许与解决方案trait/case object s是更灵活,但另一方面有更多的管道,你需要做的事情可以在这个答案中看到)。

相关问题