2015-12-04 16 views
7

Tôi mới sử dụng Scala và thậm chí những gì tôi đang cố gắng đạt được quá đơn giản với Java, tôi cảm thấy bối rối với Scala.Nhận người dùng và điền vào tất cả các quyền

Điều tôi muốn là có được User và sau đó điền Permission bằng truy vấn khác và dựa trên số Role và số cá nhân Permissions của mình.

Cho đến khi biết tôi có đoạn mã sau:

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

} 

tôi bị các lỗi sau đây:

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

'case u =>' sẽ khớp với bất kỳ thứ gì. Nếu bạn muốn thay đổi Option nếu nó là 'Some' và để nó' None' khác, bạn có thể sử dụng 'map'. Tôi không thực sự biết làm thế nào để giúp đỡ với những thứ khác như tôi không biết slick nhưng có thể cố gắng chú thích các loại bạn mong đợi và để cho trình biên dịch cho bạn biết nơi bạn thất bại. –

+1

Các thông báo lỗi bạn đang nhận được, nếu bạn đọc chúng chặt chẽ, đã cho bạn biết những vấn đề của bạn là gì. Có thông báo lỗi cụ thể nào bạn đang gặp khó khăn khi diễn giải ...? –

+0

Sẽ dễ dàng hơn để gỡ lỗi nếu bạn có thể cung cấp lược đồ các bảng và các phương thức của mình. – mohit

Trả lời

0

Bất cứ khi nào bạn làm việc với một phi hiểu với một yield bạn phải hiểu rằng quý khách làm việc với một số loại "bọc" giá trị (monad). Nó có thể là Future, một số List, một số Option hoặc bất kỳ thứ gì khác đơn thuần.

Vì vậy, mô hình là loại như thế này:

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

Nếu bạn đang làm việc với Future, sau đó bạn có thể sử dụng các quy tắc:

  • Tất cả mọi thứ ở bên phải của một <- phải là một Future
  • Mọi thứ ở bên trái của <- là giá trị "chưa được mở"
  • Giá trị của toàn bộ cho-hiểu sẽ là bất cứ là trên yield bọc trong một Future

Các quy tắc là như nhau cho List, Option, vv Tuy nhiên, bạn không thể trộn và kết hợp trong cùng một cho-hiểu.

Một trong các lỗi gợi ý rằng kết quả của câu lệnh match là loại Object, có nghĩa là scala không thể tìm ra loại chung cho tất cả các trường hợp trong trận đấu. Bạn muốn tất cả các trường hợp để tạo ra một Future (vì đó là những gì chúng tôi đang làm việc với điều này cho hiểu).

tôi đoán, bạn cần phải thay thế:

case None => None 

với:

case None => Future.successful(None) 

Nhưng thật khó để biết chắc chắn mà không cần biết thêm.

Về việc đơn giản hơn trong Java: Không chính xác. Điều gì làm cho nó phức tạp hơn một chút không phải là ngôn ngữ, nhưng thực tế là rất nhiều phương thức không đồng bộ. Nếu bạn đã làm nó đồng bộ trong scala, nó sẽ đơn giản như java, nếu không nhiều hơn. Nhưng sau đó bạn sẽ được chặn một thread mỗi khi bạn đang chờ đợi kết quả, đó là trường hợp với java (giả sử các cuộc gọi đồng bộ).

Các vấn đề liên quan