如何在光滑的表映射中省略 case 类字段? [英] How can I omit case class fields in a slick table mapping?

查看:26
本文介绍了如何在光滑的表映射中省略 case 类字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在自学一些 Scala,目前我正在使用 slick (3.1) + play 框架,所以这里的答案可能很简单,但我遗漏了一些明显的东西.我有以下模型和表格

I'm teaching myself some Scala and am currently getting my feet wet with slick (3.1) + play framework, so maybe the answer is simple here and I'm missing something obvious. I have the following model and Table

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)
  }

现在上面的工作正常,但我想向 User 案例类添加一些字段,这些字段没有保存在 USER 表中,即权限和角色,如下所示:

Now this above works just fine as it is, but I'd like to add some fields to the User case class that aren't saved in the USER table, namely permissions and roles, like this:

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

那些应该作为用户 ID -> 权限/角色映射(简单的一对多关系)进入各自的表.

Those are supposed to go into their own respective tables as userid -> permission/role mappings (simple one to many relationships).

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

Ultimately those should be queried too, but for now I'd just like to ignore the additional fields (purely as an exercise). How do I adjust the original projection in the table to omit/ignore those new fields? Obviously the original mapping

 def * = (id, username, passwordHash, email) <>((User.apply _).tupled, User.unapply)

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

doesn't work anymore since the touple doesnt match the case class. As far as I can tell it shouldnt be too hard since <> just takes two functions that convert from a touple to a User instance and vice versa and those functions should just ignore the new fields (or fill them with their default values). But I can't figure out how to express that.

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

I tried adding a new apply() with a shorter signature to the User companion object, but then I get an error that basically tells me that slick doesnt know which apply() to use. Makes sense, but I dont know how to reference one or the other. I did the same thing with an additional constructor for User, the result is the same problem. And I tried writing basic conversion functions like this:

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)
  }

遗憾的是,这也会导致错误:

Sadly that also leads to an error:

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

推荐答案

你的问题是你的constructUser是4个参数的函数,而它应该是单个Tuple4的函数代码>

Your trouble here is your constructUser is function of 4 parameters, while it supposed to be function of single Tuple4

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

Try to add type signatures.
This sample works for instance ( some simplifications included )

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)

这篇关于如何在光滑的表映射中省略 case 类字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆