2015-10-29 30 views
2

我在教自己一些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) 
    } 

现在这上面的作品就好了,因为它是,但我想一些字段添加到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) 

这些都应该进入他们各自的表作为用户标识 - >许可/角色映射(简单的一对多关系)。

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

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

不工作了,因为touple不符合案例类。据我可以告诉它不应该太难,因为<>只需要两个功能,从一个touple转换到一个用户实例,反之亦然,这些功能应该忽略新的字段(或填充他们的默认值)。但我无法弄清楚如何表达这一点。

我尝试添加一个新的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) 
    } 

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

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

回答

10

你这里的麻烦是你的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) 
+1

这工作和非常有意义。谢谢。可悲的是我还不能满足。 :) – user5504273

+0

@Odomontois谢谢。在上述情况下,答案也适用于我(即 - 将一些字段添加到用户案例类中,但未保存在USER表中)。但在我的情况下(例如),我已经添加另一个表作为USER表中的字段。我添加了“accessToken:Option [AccessToken] = None”和“oauthClient:Option [Client] = None”,而不是“权限,角色”。但我想要映射这些值。我该怎么做?你可以请检查下面的问题 - http://stackoverflow.com/q/37183156/1584121 – SKK

相关问题