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

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

问题描述

我正在自学一些Scala,目前正在使用光滑的(3.1)+播放框架来弄湿我的脚,所以也许答案在这里很简单,而我却缺少了一些明显的东西.我有以下模型和表格

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类不匹配.据我所知,它不应该太难,因为<>只是采用了从一个touple转换为一个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)

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

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