2015-12-04 16 views
7

Ich bin neu in Scala und sogar was ich versuche zu erreichen ist zu einfach mit Java, ich fühle mich verwirrt mit Scala.Holen Sie sich Benutzer und füllen Sie alle Berechtigungen

Was ich will, ist eine User zu bekommen und dann füllen seine Permission eine weitere Abfrage und basiert auf seiner Role und seine individuellen Permissions.

Bis weiß, ich habe den folgenden Code:

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

} 

ich die folgenden Fehler wurde:

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 
+1

'Fall u =>' passt alles zusammen. Wenn Sie die Option ändern möchten, wenn sie "Some" ist, und die Option "None" aufheben, können Sie 'map' verwenden. Ich weiß nicht wirklich, wie ich mit anderen Dingen helfen kann, da ich nicht glatt weiß, aber vielleicht versuche, Typen, die du erwartest, mit Anmerkungen zu versehen und dich vom Compiler darüber informieren zu lassen, wo du versagst. –

+1

Die Fehlermeldungen, die Sie bekommen, wenn Sie sie genau lesen, sagen Ihnen bereits, was Ihre Probleme sind. Gibt es eine bestimmte Fehlermeldung, bei der Sie Schwierigkeiten haben zu interpretieren ...? –

+0

Es wird einfacher zu debuggen, wenn Sie die Schemas Ihrer Tabellen und die Methoden geben können. – mohit

Antwort

0

Jedes Mal, wenn Sie mit einer Arbeit für Verständnis mit einem yield Sie müssen verstehen, dass Sie ein mit einer Art "gewickeltem" Wert (Monade) arbeiten. Es kann ein Future, ein List, ein Option oder irgendetwas anderes sein, das monadisch ist.

So ist das Muster der Art wie folgt aus:

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

Wenn Sie mit Future arbeiten, dann können Sie diese Regeln verwenden:

  • Alles, was rechts von einem <- a sein muss Future
  • Alles auf der linken Seite von einem <- ist der "ausgepackte" Wert
  • Der Wert des gesamten für Verständnis wird, was auf die in einem Future gewickelt yield ist

Die Regeln sind die gleichen für List, Option usw. Aber man kann nicht innerhalb derselben für Verständnis mischen und anzupassen.

Einer der Fehler deutet darauf hin, dass das Ergebnis Ihrer match-Anweisung vom Typ Object ist, was bedeutet, dass scala für alle Fälle in der Übereinstimmung keinen gemeinsamen Typ herausfinden konnte. Sie möchten, dass alle Fälle einen Future erzeugen (da wir mit diesem Verständnis arbeiten).

Meine Vermutung, müssen Sie ersetzen:

case None => None 

mit:

case None => Future.successful(None) 

Aber es ist schwer, sicher, ohne weitere Informationen zu kennen.

In Java ist es einfacher: Nicht genau. Was es etwas komplexer macht, ist nicht die Sprache, sondern die Tatsache, dass viele der Methoden asynchron sind. Wenn Sie es synchron in scala tun würden, wäre es genauso einfach wie Java, wenn nicht mehr. Aber dann würden Sie jedes Mal einen Thread blockieren, wenn Sie auf Ergebnisse warten, was bei Java der Fall ist (synchrone Aufrufe vorausgesetzt).