【问题标题】:Get user and fill all permissions获取用户并填写所有权限
【发布时间】:2016-03-09 12:08:25
【问题描述】:

我是 Scala 的新手,即使我想用 Java 实现的目标太简单了,我对 Scala 感到困惑。

我想要的是获得一个User,然后使用另一个查询并根据他的Role 和他的个人Permissions 填写他的Permission

直到知道我有以下代码:

/**
* 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)

}

我收到以下错误:

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

【问题讨论】:

  • case u =&gt; 将匹配任何内容。如果您想修改 Option 如果它是 Some 并保留它 None 其他方式,您可以使用 map 。我真的不知道如何帮助其他事情,因为我不知道 slick 但也许尝试注释您期望的类型并让编译器告诉您失败的地方。
  • 如果您仔细阅读,您收到的错误消息已经告诉您问题所在。您是否有难以解释的特定错误消息...?
  • 如果你能给出你的表的模式和方法,调试起来会更容易..

标签: scala playframework-2.0 slick slick-3.0 silhouette


【解决方案1】:

每当您使用yield 进行理解时,您必须了解您使用某种“包装”值(monad)。它可以是 FutureListOption 或任何其他单子。

所以模式有点像这样:

for {
  someValue <- someWrappedValue()
  someOtherValue <- someWrappedOtherValue(someValue)
} yield someOtherValue

如果您使用的是Future,那么您可以使用这些规则:

  • &lt;- 右侧的所有内容都必须是 Future
  • &lt;- 左侧的所有内容都是“展开”值
  • 整个 for-comprehension 的值将是 yield 上包含在 Future 中的任何内容

ListOption等规则相同,但不能在同一个理解范围内混搭。

其中一个错误提示您的match 语句的结果是Object 类型,这意味着scala 无法找出匹配中所有情况的通用类型。您希望所有案例都生成一个Future(因为这是我们在本次理解中使用的内容)。

我猜,你需要更换:

case None => None

与:

case None => Future.successful(None)

但如果没有更多信息,很难确定。

关于它在 Java 中更简单:不完全是。让它变得更复杂的不是语言,而是很多方法都是异步的。如果你要在 scala 中同步进行,它会像 java 一样简单,如果不是更多的话。但是每次等待结果时都会阻塞一个线程,java就是这种情况(假设同步调用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多