2017-02-13 61 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是更靈活,但另一方面有更多的管道,你需要做的事情可以在這個答案中看到)。

相關問題