Slick 3.0.0 - multiple inserts depending on each other with return value

817 views Asked by At

I'm trying to update to Slick 3.0.0 (reactive Slick), however I can't get the most basic stuff to work. Before I could just do something like db.withTransaction { ... } and it would run, however I can't even get this to compile:

def insertNewFacebookUser(
  facebookId: String,
  email: String,
  firstName: String,
  lastName: String
) = {
  val user =
  (Users.map(u ⇒ (u.email, u.firstName, u.lastName)) returning Users) +=
    ((email, firstName, lastName))

  FacebookAuths.map(f ⇒ (f.userId, f.facebookId)) += ((user.id, facebookId))

  user
}

This just complains that user.id is wrapped in some DBIOAction, how should I write this so it compiles?

Thanks

1

There are 1 answers

1
Klugscheißer On BEST ANSWER

Without knowing more about the schema:

def insertNewFacebookUser(
  facebookId: String,
  email: String,
  firstName: String,
  lastName: String
): DBIOAction[???, ???, ???] = for {
      userId <- Users returning Users.map(_.id) += (email, firstName, lastName)
       _     <- FacebookAuths += (userId, facebookId)
    } yield (User(userId, email, firstName, lastName))

val user: Future[User] = db.run(insertNewFaceBookUser(....)

I'm not sure what the exact type of DBIOAction will be returned as it depends on your schema, hence the ???. Everything is wrapped in an action of sorts so when you attempt to use the userId directly in the insert to FacebookAuths, it's the wrong type. Instead what you want to do is map/flatMap on the returned results and compose your fuller action. The for {...} yield is just sugar on map and flatMap. You then run your action to get a Future of your result. You can then map on that as you need to.