4

In many slick examples in which the type parameter of the table is a case class and the table has an auto-incrementing primary key, I have seen an Option used in the case class for the id field:

case class Item(id : Option[Long], name : String)

object Items extends Table[Item]("item"){
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def * = id.? ~ name <> (Item.apply _, Item.unapply _)
}

This kind of makes sense to me, because the id field will have no meaningful value until the object is inserted into the table. However, database queries will always give me back Items that have the id set to something and it gets extremely tedious always folding or pattern matching on something that I know will not be None. I could just put a 0L in the id field when I create a new Item, but this doesn't seem like a good choice.

How is this typically dealt with? Are those the only two options?

This related question has some possible answers in it. The question itself is about a much more specific issue with postgres though.

Community
  • 1
  • 1
mushroom
  • 6,201
  • 5
  • 36
  • 63

1 Answers1

1

Update: see Rikards comment below

You could just call .get in the places where you know id is not None. Which is what people usually do I suppose.

An alternative would be having two different classes. One with an id field and one without. Or an ID trait which you only mix in for classes that have an ID.

trait WithID{ def id : Int }
case class Person(name: String)
// create a person with id
(newid:Int,name:String) => new Person(name) with WithID{ def id = newid }

The mapping you have to provide to Slick will be more verbose, but the usage code will be simpler and type-safe. I believe @nafg has an abstraction for this in https://github.com/nafg/slick-additions but I may be mistaken.

cvogt
  • 11,260
  • 30
  • 46
  • Tried to make this an edit but it was rejected. "Time saver for future googlers: Slick 2.0 will now automatically exclude AutoInc fields by default when inserting data." – Rikard Feb 10 '15 at 08:48