如何使用Anorm管理scala枚举?

时间:2014-06-13 20:34:30

标签: scala enums anorm

我想通过使用枚举创建用户角色(认为这是最好的主意)。

我该如何处理?

我目前的代码如下:

object UserRole extends Enumeration {
  type UserRole = Value
  val admin, user, manager = Value
}    
case class User(id: Long, firstname: String, lastname: String, password: String, email: String, role: UserRole)

那么我应该如何定义用户“简单”:

val simple = {
    get[Long]("user.id") ~
      get[String]("user.firstname") ~
      get[String]("user.lastname") ~
      get[String]("user.password") ~
      get[String]("user.email") ~
      get[UserRole]("user.role")  map {
      case id~firstname~lastname~password~email~role => User(id, firstname, lastname, password, email, role)
    }
  }

我应该如何将其保存到数据库?

CREATE TABLE user (
    id integer NOT NULL DEFAULT nextval('user_id_seq'),
    firstname varchar(60),
    lastname varchar(60),
    password varchar(255),
    email varchar(60),
    role varchar(40)
);

2 个答案:

答案 0 :(得分:2)

Anorm不支持​​scala枚举(在我看来,scala枚举非常糟糕)。我通常做的是用它自己的解析器和表空间创建另一个case类,并将JOIN创建给相关的查询。 UserRole可以在User内通过User.simple进行解析来解析case class UserRole(id: Long, name: String) object UserRole { val simple: RowParser[UserRole] = { get[Long]("roles.id") ~ get[String]("roles.name") map { case id~name => UserRole(id, name) } } } case class User(id: Long, firstname: String, lastname: String, password: String, email: String, role: UserRole) object User { val simple: RowParser[User] = { get[Long]("user.id") ~ get[String]("user.firstname") ~ get[String]("user.lastname") ~ get[String]("user.password") ~ get[String]("user.email") ~ UserRole.simple map { case id~firstname~lastname~password~email~role => User(id, firstname, lastname, password, email, role) } } }

{{1}}

答案 1 :(得分:0)

作为另一种选择,您可以使用密封特征为角色建模。

sealed trait UserRole
case object Admin extends UserRole
case object User extends UserRole
case object Manager extends UserRole

然后为您的类型提供一个anorm阅读器。

implicit val column: Column[UserRole] = {
  Column.nonNull1 { (value, meta) =>
    val MetaDataItem(qualified, nullable, clazz) = meta
    value match {
      case "Admin" => Right(Admin)
      case "User" => Right(User)
      case "Manager" => Right(Manager)
      case unknown => Left(TypeDoesNotMatch(s"unknown UserRole from $unknown"))
    }
  }
}

然后,您可以使用行解析器中的类型,如get[UserRole]

请注意字符串上的匹配,这显然是一个非常好的预算,但你明白了。

有关详细信息,请参阅此处的文档https://playframework.com/documentation/2.4.x/ScalaAnorm#Column-parsers