例如我有这个案例类:
case class User(
var identityId: IdentityId, //Its a user created class
var firstName: String,
var lastName: String,
var fullName: String,
var email: Option[String],
var avatarUrl: Option[String],
var authMethod: AuthenticationMethod,
var oAuth1Info: Option[OAuth1Info] = None,
var oAuth2Info: Option[OAuth2Info] = None,
var passwordInfo: Option[PasswordInfo] = None) extends Identity {
def this() = this(null, "", "", "", None, None, null, None, None, None)
}
它实际上是一个secSecocial标识,现在identityId是案例类的对象:
case class IdentityId(
var userId:String,
var providerId:String
)
那么如何为像这样的情况创建一个投影类呢?如果我必须创建一个类似String的投影类数据类型,那么它本来就没有问题,但用户定义的对象和类呢?
答案 0 :(得分:6)
我做了一些研究,并在这里找到了一些非常有用的答案 Link1和Link2
第二个链接没有PasswordInfo的实现,所以,这里我提供了自己的实现,虽然这种方法看起来更多一些代码,任何人都可以建议一个更有效的方法,如果有的话:
*注意:第二个链接非常有用,它实际上是整个工作项目示例基于Play,Slick和SecureSocial感谢Lunatech和其他人。
class Users(tag: Tag) extends Table[User](tag, "user") {
implicit def string2AuthenticationMethod = MappedColumnType.base[AuthenticationMethod, String](
authenticationMethod => authenticationMethod.method,
string => AuthenticationMethod(string))
implicit def tuple2OAuth1Info(tuple: (Option[String], Option[String])): Option[OAuth1Info] = tuple match {
case (Some(token), Some(secret)) => Some(OAuth1Info(token, secret))
case _ => None
}
implicit def tuple2OAuth2Info(tuple: (Option[String], Option[String], Option[Int], Option[String])): Option[OAuth2Info] = tuple match {
case (Some(token), tokenType, expiresIn, refreshToken) => Some(OAuth2Info(token, tokenType, expiresIn, refreshToken))
case _ => None
}
implicit def tuple2PasswordInfo(tuple: (Option[String], Option[String], Option[String])) = tuple match {
case (Some(hasher), Some(password), salt) =>
Some(PasswordInfo(hasher, password, salt))
case _ => None
}
implicit def tuple2IdentityId(tuple: (String, String)): IdentityId = tuple match {
case (userId, providerId) => IdentityId(userId, providerId)
}
def uid = column[Long]("id", O.PrimaryKey, O.AutoInc)
def userId = column[String]("userId")
def providerId = column[String]("providerId")
def email = column[Option[String]]("email")
def firstName = column[String]("firstName")
def lastName = column[String]("lastName")
def fullName = column[String]("fullName")
def authMethod = column[AuthenticationMethod]("authMethod")
def avatarUrl = column[Option[String]]("avatarUrl")
// oAuth 1
def token = column[Option[String]]("token")
def secret = column[Option[String]]("secret")
// oAuth 2
def accessToken = column[Option[String]]("accessToken")
def tokenType = column[Option[String]]("tokenType")
def expiresIn = column[Option[Int]]("expiresIn")
def refreshToken = column[Option[String]]("refreshToken")
//PasswordInfo
def hasher = column[Option[String]]("hasher")
def password = column[Option[String]]("password")
def salt = column[Option[String]]("salt")
def * : ProvenShape[User] = {
val shapedValue = (
userId,
providerId,
firstName,
lastName,
fullName,
email,
avatarUrl,
authMethod,
token,
secret,
accessToken,
tokenType,
expiresIn,
refreshToken,
hasher,
password,
salt).shaped
shapedValue.<>({
tuple =>
User.apply(
identityId = tuple2IdentityId(tuple._1, tuple._2),
firstName = tuple._3,
lastName = tuple._4,
fullName = tuple._5,
email = tuple._6,
avatarUrl = tuple._7,
authMethod = tuple._8,
oAuth1Info = (tuple._9, tuple._10),
oAuth2Info = (tuple._11, tuple._12, tuple._13, tuple._14),
passwordInfo = (tuple._15, tuple._16, tuple._17))
}, {
(u: User) =>
Some {
(u.identityId.userId,
u.identityId.providerId,
u.firstName,
u.lastName,
u.fullName,
u.email,
u.avatarUrl,
u.authMethod,
u.oAuth1Info.map(_.token),
u.oAuth1Info.map(_.secret),
u.oAuth2Info.map(_.accessToken),
u.oAuth2Info.flatMap(_.tokenType),
u.oAuth2Info.flatMap(_.expiresIn),
u.oAuth2Info.flatMap(_.refreshToken),
u.passwordInfo.map(_.hasher),
u.passwordInfo.map(_.password),
u.passwordInfo.flatMap(_.salt))
}
})
}
}