Слик DBIO в будущее [Либо [Ошибка, пользователь]] - PullRequest
0 голосов
/ 30 октября 2018

Я новичок в Slick, и у меня есть проблема ниже. Я пытаюсь реализовать метод createUser, как здесь определено

def createUser(data: UserCreate): Future[User] = {
   val userRow = User(userId = UUID.randomUUID(),
     email = data.email, password = data.password,
     firstName = data.firstName, lastName = data.lastName, balance = 0)
   val userAction =
     Users
       .filter(_.email === data.email).result.headOption.flatMap {
       case Some(res) =>
         //          mylog("product was there: " + product)
           DBIO.successful(res)
       case None =>
         //          mylog("inserting product")
         (Users returning Users.map(_.id) into (
           (user, newId) => user.copy(id = Some(newId)))
           ) += userRow
     }
       .transactionally
   db.run(userAction)
}

Проблема в том, что в случае, если пользователь уже существует, я хочу дать ошибку, поэтому подпись метода должна быть

def createUser(data: UserCreate): Future[Either[RecordAlreadyExists, User]]

Можете ли вы представить, как я могу это сделать? без поднятия Throwable?

1 Ответ

0 голосов
/ 31 октября 2018

ИМХО, это случай преобразования Future с, а не вопрос о слике.

Как насчет чего-то вроде:

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.concurrent.Future
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global

case object RecordAlreadyExists extends RuntimeException

case class User(id: Int)

Future[User](throw new RuntimeException).
  transformWith {
  case Success(user) => Future.successful(Right[RecordAlreadyExists.type, User](user))
  case Failure(_) => Future.successful(Left[RecordAlreadyExists.type, User](RecordAlreadyExists))
}


// Exiting paste mode, now interpreting.

import scala.concurrent.Future
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global
defined object RecordAlreadyExists
defined class User
res3: scala.concurrent.Future[scala.util.Either[RecordAlreadyExists.type,User]] = Future(<not completed>)

вместо того, чтобы поймать все, что у меня есть, вы могли бы сопоставить это исключение из конкретной БД, которое означало бы, что «пользователь уже существует»

Примечание: В моем примере Future[User](throw new RuntimeException) соответствует вашей полной функции, указанной в вопросе.

...