我试图在scala中使用光滑(使用独角兽)查找用户。这是我的代码:
class UserRepository extends BaseIdRepository[UserId, User, Users](TableQuery[Users]) with IdentityService[User] {
/**
* Retrieve the User associated with the given LoginInfo, if any. This method
* is required by Silhouette.
* @param loginInfo
*/
override def retrieve(loginInfo: LoginInfo): Future[Option[User]] = {
Future.successful {
val loginInfoRepository = new LoginInfoRepository
loginInfoRepository.find(loginInfo) match {
case Some(retrievedLoginInfo) =>
val userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
// problem here...
userLoginInfoJunctionRepository.forB(retrievedLoginInfo.id).firstOption
case None => None
}
}
}
}
class LoginInfoRepository extends BaseIdRepository[DbLoginInfoId, DbLoginInfo, LoginInfos](TableQuery[LoginInfos]) {
def find(loginInfo: LoginInfo) = query.filter(
l =>
l.providerID == loginInfo.providerID &&
l.providerKey == loginInfo.providerKey
).firstOption
}
在上面标记的行上,intellij打印"类型不匹配。预期DbLoginInfoId,实际选项[DbLoginInfoId]"。
我是否在选项中有选项,因此retrievedLoginInfo
实际上是Option[retrievedLoginInfo]
?如何正确解压缩,以便我可以访问retrievedLoginInfo
?
答案 0 :(得分:2)
id
上LoginInfo
的{{1}}类似Option[DbLoginInfoId]
,但forB
需DbLoginInfoId
。
您需要映射retrievedLoginInfo.id
以提取实际值。您可以通过更好的理解来重构整个事物,例如:
for {
retrievedLoginInfo <- loginInfoRepository.find(loginInfo)
id <- retrievedLoginInfo.id
userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
res <- userLoginInfoJunctionRepository.forB(id).firstOption
} yield res
答案 1 :(得分:1)
对我来说很好看。我认为这个问题中缺少一些信息吗?
一旦我在这段代码中填充了足够的上下文,它就会编译。此代码中您的部分未经更改:
import scala.concurrent.Future
package object foo {
trait LoginInfo {
def providerID: Any
def providerKey: Any
}
abstract class BaseIdRepository[A, B, C](x: Any)
trait IdentityService[A] {
def retrieve(loginInfo: LoginInfo): Future[Option[User]]
}
trait User {
def id: UserId
}
trait UserId
trait Users
def TableQuery[A] = ???
class UserLoginInfoJunctionRepository {
def forB(x: UserId): QueryResult[User] = ???
}
trait DbLoginInfoId
trait DbLoginInfo
trait LoginInfos
trait QueryResult[A] {
def firstOption: Option[A] = ???
}
class Query {
def filter(f: LoginInfo => Boolean): QueryResult[User] = ???
}
val query = new Query()
// ----
class UserRepository extends BaseIdRepository[UserId, User, Users](TableQuery[Users]) with IdentityService[User] {
/**
* Retrieve the User associated with the given LoginInfo, if any. This method
* is required by Silhouette.
* @param loginInfo
*/
override def retrieve(loginInfo: LoginInfo): Future[Option[User]] = {
Future.successful {
val loginInfoRepository = new LoginInfoRepository
loginInfoRepository.find(loginInfo) match {
case Some(retrievedLoginInfo) =>
val userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
// problem here...
userLoginInfoJunctionRepository.forB(retrievedLoginInfo.id).firstOption
case None => None
}
}
}
}
class LoginInfoRepository extends BaseIdRepository[DbLoginInfoId, DbLoginInfo, LoginInfos](TableQuery[LoginInfos]) {
def find(loginInfo: LoginInfo) = query.filter(
l =>
l.providerID == loginInfo.providerID &&
l.providerKey == loginInfo.providerKey
).firstOption
}
}
如果您可以将问题减少到一个最小的例子,那就容易多了。