如何在光滑表映射中省略案例类字段?

use*_*273 7 scala jdbc playframework slick slick-3.0

我正在教自己一些Scala,目前我正在使用光滑的(3.1)+播放框架,所以也许这里的答案很简单,我错过了一些明显的东西.我有以下型号和表格

case class User(id: Long = -1,
                username: String,
                passwordHash: String,
                email: Option[String] = None) 

class Users(tag: Tag) extends Table[User](tag, "USERS") {
    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
    def username = column[String]("USERNAME")
    def email = column[Option[String]]("EMAIL")
    def passwordHash = column[String]("PASSWD_HASH")
    def * = (id, username, passwordHash, email) <>((User.apply _).tupled, User.unapply)
  }
Run Code Online (Sandbox Code Playgroud)

现在上面这个工作正常,但是我想在Usercase 表中添加一些保存在USER表中的字段,即权限和角色,如下所示:

case class User(id: Long = -1,
                username: String,
                passwordHash: String,
                email: Option[String] = None,
                permissions: Seq[String] = Seq.empty,
                roles: Seq[String] = Seq.empty) 
Run Code Online (Sandbox Code Playgroud)

这些应该作为userid - > permission/role mappings(简单的一对多关系)进入各自的表.

最终那些也应该被查询,但是现在我只想忽略其他领域(纯粹作为练习).如何调整表格中的原始投影以省略/忽略这些新字段?显然是原始的映射

 def * = (id, username, passwordHash, email) <>((User.apply _).tupled, User.unapply)
Run Code Online (Sandbox Code Playgroud)

由于touple与案例类不匹配,因此不再起作用.据我所知,它不应该太难,因为<>只需要两个从touple转换为User实例的函数,反之亦然,这些函数应该忽略新的字段(或用它们的默认值填充它们).但我无法弄清楚如何表达这一点.

我尝试向伴侣对象添加一个apply()带有较短签名的新内容User,但后来我得到一个错误,基本上告诉我光滑的不知道apply()要使用哪个.有道理,但我不知道如何引用其中一个.我用一个额外的构造函数做了同样的事情User,结果是同样的问题.我尝试编写这样的基本转换函数:

class Users(tag: Tag) extends Table[User](tag, "USERS") {

    def constructUser = (id: Long, username: String, passwordHash: String, email: Option[String]) =>
      User(id, username, passwordHash, email)

    def extractUser = (user: User) => user match {
      case User(id, username, passwordHash, email, permissions, roles) =>
        Some((id, username, passwordHash, email))
    }

    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
    def username = column[String]("USERNAME")
    def email = column[Option[String]]("EMAIL")
    def passwordHash = column[String]("PASSWD_HASH")
    def * = (id, username, passwordHash, email) <>(constructUser, extractUser)
  }
Run Code Online (Sandbox Code Playgroud)

可悲的是,这也导致了一个错误:

[error]  found   : (Long, String, String, Option[String]) => models.User
[error]  required: ? => ?
[error]     def * = (id, username, passwordHash, email) <>(constructUser, deconstructUser)
Run Code Online (Sandbox Code Playgroud)

Odo*_*ois 18

你在这里的麻烦是你constructUser的4个参数的功能,而它应该是单一的功能Tuple4

尝试添加类型签名.
此示例适用于(例如,包括一些简化)

type Data = (Long, String, String, Option[String])

def constructUser: Data => User = {
  case (id, username, passwordHash, email) => User(id, username, passwordHash, email)

}
def extractUser: PartialFunction[User, Data] = {
  case User(id, username, passwordHash, email, _, _) =>
    (id, username, passwordHash, email)
}

def * = (id, username, passwordHash, email) <> (constructUser, extractUser.lift)
Run Code Online (Sandbox Code Playgroud)

  • 这很有效,而且很有意义。谢谢你。遗憾的是我还不能投票。:) (2认同)