Scala:类型不匹配;发现:scala.concurrent.Future [Option [models.Account]]必需:选项[?]

时间:2016-06-12 07:41:36

标签: scala

然后给出以下代码:

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)之类的东西。有没有更好的方法来构建/组织此代码?我可以遵循/使用的任何模式吗?

0 个答案:

没有答案
相关问题