Question

The Slick DSL allows two ways to create optional fields in tables.

For this case class:

case class User(id: Option[Long] = None, fname: String, lname: String)

You can create a table mapping in one of the following ways:

object Users extends Table[User]("USERS") {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def fname = column[String]("FNAME")
    def lname = column[String]("LNAME")
    def * = id.? ~ fname ~ lname <> (User, User.unapply _)
  }

and

  object Users extends Table[User]("USERS") {
    def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
    def fname = column[String]("FNAME")
    def lname = column[String]("LNAME")
    def * = id ~ fname ~ lname <> (User, User.unapply _)
  }
}

What is the difference between the two? Is the one the old way and the other the new way, or do they serve different purposes?

I prefer the second choice where you define the identity as optional as part of the id definition because it's more consistent.

Was it helpful?

Solution

The .? operator in the first one allows you to defer the choice of having your field be optional to the moment of defining your projections. Sometimes that's not what you want, but defining your PK to be an Option is perhaps a bit funny because one might expect a PK to be NOT NULL.

You can use .? in additional projections besides *, for example:

def partial = id.? ~ fname

Then you could do Users.partial.insert(None, "Jacobus") and not worry about fields you're not interested in.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top