然后给出以下代码:
AccountsDAO.scala:
def find(id: EntityId): Future[Option[Account]] =
collection.find(Json.obj(Fields.Id -> id)).one[Account]
AccountService.scala:
def getAccount(id: Option[Credentials]) = id.flatMap {
accountId => accountDAO.find(accountId.accountId) //Throws an error
}
上面的注释行引发了这个错误:
type mismatch; found : scala.concurrent.Future[Option[models.Account]] required: Option[?]
我错过了什么?为什么flattop返回Option[?]
。如果我将getAccount
方法的返回类型更改为:
def getAccount(id: Option[Credentials]): Future[Option[Account]] = id.flatMap {
accountId => accountDAO.find(accountId.accountId) //Still throws an error
}
我收到以下错误:
type mismatch; found : Option[Nothing] required: scala.concurrent.Future[Option[models.Account]]
发生了什么事?我错过了什么?
提前致谢。
编辑:这是控制器中的代码以及我要做的事情:
def auth = Action.async(parse.json) { request =>
{
val authRequest = request.body.validate[AuthRequest]
authRequest.fold(
errors => Future(BadRequest),
auth => {
//First verify username and password
val authRequestResult = for {
validCredentials <- credentialsManager.checkEmailPassword(auth.email, auth.password)
account:Option[Account] <- accountManager.getAccount(validCredentials)
session:Session <- sessionManager.createSession(account.get.id, account.get.roles)
touchedSession <- sessionManager.TouchSession(session.id)
} yield AuthResponse(session.id, session.token, account.get.id, account.get.roles)
authRequestResult map {
case res: AuthResponse => Ok(Json.toJson(res))
case _ => NotFound
}
})
}
}
上面的checkEmailPassword方法返回Future [Option]:
def checkEmailPassword(email: String, password: String) =
for {
credentials <- credentialsDAO.find(AuthType.EmailPassword, email)
validPassword <- BCrypt.checkFuture(password, credentials)
} yield (credentials)
credentialsDAO.find:
def find(authType: AuthType.Value, authAccountId: String) =
collection.find(
Json.obj(Fields.AuthType → authType,
Fields.AuthAccountId → authAccountId)).one[Credentials].recover(wrapLastError)
因此,当checkEmailPassword
返回Option [Credentials]对象时,如果它返回for comprehension
,是否可以假设控制器中的None
将不再执行?然后我可以说account:Option[Account] <- accountManager.getAccount(validCredentials.get.id)
之类的东西。有没有更好的方法来构建/组织此代码?我可以遵循/使用的任何模式吗?