在 Slick 中过滤和混合 monads for comprehension 和 Cats
Filtering and mixing monads in Slick for comprehension and Cats
我有以下 objective:
使用以下计算流程创建一个添加用户的 monad:
- 检查是否存在具有指定电子邮件的用户,如果他不存在则:
- 检查给定的凭据是否正确(密码足够长等)。如果他们没问题,那么:
- 将用户保存到数据库
我的第一个 "draft" 会是这样的:
val work: DBIO[UserId] = for {
userO <- UserRepository.findByEmail(createdUser.email) //userO is Option[User]
//This won't work cause Action.withFilter doesnt exist
if userO.isEmpty
//as above, validate user actually returns an ValidateNel[String, User]
if User.validateUser(createdUser.email, createdUser.password).isValid
//Returns DBIO[UserId]
id <- UserRepository.save(createdUser)
} yield id
任何想法是什么是我可以 db.run(...) 在一个一元计算中写下它的最佳方法?我正在使用 Cats + Slick 3.0。
如果有帮助,我还从 https://groups.google.com/forum/?fromgroups#!topic/scalaquery/HrvrvyEIopw 写了一个简单的隐式 dbioMonad。
这个不能用于理解,如果可以接受请告诉我。
val work: DBIO[UserId] = {
UserRepository.findByEmail(createdUser.email).flatMap {
case Some(_) => DBIO.failed(new Exception("Provided email is already taken"))
case _ =>
if(User.validateUser(createdUser.email, createdUser.password).isValid) {
UserRepository.save(createdUser)
} else {
DBIO.failed(new Exception("User validation has failed"))
}
}.transactionally
}
我有以下 objective: 使用以下计算流程创建一个添加用户的 monad:
- 检查是否存在具有指定电子邮件的用户,如果他不存在则:
- 检查给定的凭据是否正确(密码足够长等)。如果他们没问题,那么:
- 将用户保存到数据库
我的第一个 "draft" 会是这样的:
val work: DBIO[UserId] = for {
userO <- UserRepository.findByEmail(createdUser.email) //userO is Option[User]
//This won't work cause Action.withFilter doesnt exist
if userO.isEmpty
//as above, validate user actually returns an ValidateNel[String, User]
if User.validateUser(createdUser.email, createdUser.password).isValid
//Returns DBIO[UserId]
id <- UserRepository.save(createdUser)
} yield id
任何想法是什么是我可以 db.run(...) 在一个一元计算中写下它的最佳方法?我正在使用 Cats + Slick 3.0。 如果有帮助,我还从 https://groups.google.com/forum/?fromgroups#!topic/scalaquery/HrvrvyEIopw 写了一个简单的隐式 dbioMonad。
这个不能用于理解,如果可以接受请告诉我。
val work: DBIO[UserId] = {
UserRepository.findByEmail(createdUser.email).flatMap {
case Some(_) => DBIO.failed(new Exception("Provided email is already taken"))
case _ =>
if(User.validateUser(createdUser.email, createdUser.password).isValid) {
UserRepository.save(createdUser)
} else {
DBIO.failed(new Exception("User validation has failed"))
}
}.transactionally
}