gla*_*kou 7 scala playframework-2.0 slick slick-3.0 silhouette
我是新来斯卡拉甚至我试图实现与Java太简单了,我感到困惑与斯卡拉.
我想要的是获得一个User,然后Permission使用另一个查询并根据他Role和他的个人填写他Permissions.
直到知道我有以下代码:
/**
* Finds a user by its loginInfo.
*
* @param loginInfo The loginInfo of the user to find.
* @return The found user or None if no user for the given login info could be found.
*/
def find(loginInfo: LoginInfo): Future[Option[models.admin.User]] = {
val userQuery = for {
dbLoginInfo <- loginInfoQuery(loginInfo)
dbUserLoginInfo <- Userlogininfo.filter(_.logininfoid === dbLoginInfo.id)
dbUser <- User.filter(_.userid === dbUserLoginInfo.userid)
user <- dbUser match {
case u =>
val permissionQuery = for {
dbUserPermission <- Userpermission.filter(_.userid === u.userid)
dbPermission <- Permission.filter(_.id === dbUserPermission.permissionid)
} yield dbPermission
val rolePermissionQuery = for {
dbUserRole <- Userrole.filter(_.userid === u.userid)
dbRole <- Role.filter(_.id === dbUserRole.roleid)
dbRolePermission <- Rolepermission.filter(_.roleid === dbRole.id)
dbPermission <- Permission.filter(_.id === dbRolePermission.permissionid)
} yield dbPermission
val unionPermissionQuery = permissionQuery union rolePermissionQuery
db.run(unionPermissionQuery.result).map(_.map(_.name).toList).map { permission =>
models.admin.User(
UUID.fromString(u.userid.toString),
u.firstname.toString,
u.lastname.toString,
u.jobtitle.toString,
loginInfo,
u.email.toString,
false,
Some(permission),
false)
}
case None => None
}
} yield user
db.run(userQuery.result.headOption)
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
pattern type is incompatible with expected type;
[error] found : None.type
[error] required: UserDAOImpl.this.User
[error] case None => None
[error] ^
[error] play/modules/admin/app/models/daos/impl/UserDAOImpl.scala:36: value map is not a member of Object
[error] user <- dbUser match {
[error] ^
[error] play/modules/admin/app/models/daos/impl/UserDAOImpl.scala:34: type mismatch;
[error] found : UserDAOImpl.this.Userlogininfo => slick.lifted.Query[Nothing,Nothing,Seq]
[error] required: UserDAOImpl.this.Userlogininfo => slick.lifted.Query[Nothing,T,Seq]
[error] dbUserLoginInfo <- Userlogininfo.filter(_.logininfoid === dbLoginInfo.id)
[error] ^
[error] play/modules/admin/app/models/daos/impl/UserDAOImpl.scala:33: type mismatch;
[error] found : UserDAOImpl.this.Logininfo => slick.lifted.Query[Nothing,Nothing,Seq]
[error] required: UserDAOImpl.this.Logininfo => slick.lifted.Query[Nothing,T,Seq]
[error] dbLoginInfo <- loginInfoQuery(loginInfo)
[error] ^
[error] play/modules/admin/app/models/daos/impl/UserDAOImpl.scala:69: value headOption is not a member of UserDAOImpl.this.driver.DriverAction[Seq[Nothing],UserDAOImpl.this.driver.api.NoStream,slick.dbio.Effect.Read]
[error] db.run(userQuery.result.headOption)
[error] ^
[error] 5 errors found
Run Code Online (Sandbox Code Playgroud)
每当您使用 a 进行 for 理解时,yield您都必须了解您正在使用某种“包装”值(monad)。它可以是 a Future、 a List、 anOption或任何其他单子。
所以模式是这样的:
for {
someValue <- someWrappedValue()
someOtherValue <- someWrappedOtherValue(someValue)
} yield someOtherValue
Run Code Online (Sandbox Code Playgroud)
如果您正在使用Future,那么您可以使用以下规则:
<-必须是 aFuture<-都是“展开”值yield在 a 中的任何内容FutureList、等的规则是相同的。Option但是您不能在同一个 for 理解中混合和匹配。
其中一个错误提示您的match语句结果的类型为Object,这意味着 scala 无法为匹配中的所有情况找出通用类型。你希望所有的情况都产生一个Future(因为这就是我们在这个理解中所处理的)。
我猜,你需要更换:
case None => None
Run Code Online (Sandbox Code Playgroud)
和:
case None => Future.successful(None)
Run Code Online (Sandbox Code Playgroud)
但如果没有更多信息,很难确定。
关于 Java 中的更简单:不完全是这样。让它变得更复杂的不是语言,而是很多方法都是异步的。如果你要在 scala 中同步执行它,它就会像 java 一样简单,甚至更简单。但是每次等待结果时都会阻塞一个线程,java就是这种情况(假设同步调用)。