With Slick, I am trying to project database table entries directly to the case class they represent. Following the example in the documentation, I set up a mapped projection usi
Another way to do it is to turn the objects apply method into a tuple and pass that to the <> as shown below.
package models
import play.api._
import play.api.libs.json._
import scala.slick.driver.H2Driver.simple._
case class User(
name: String,
id: Option[Int] = None
)
object User {
implicit val format = Json.format[User]
}
class UserTable(tag: Tag) extends Table[User](tag, "USERS") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("NAME", O.NotNull)
def * = (name, id.?) <> ((User.apply _).tupled, User.unapply)
}
object Users extends TableQuery(new UserTable(_)) {
val findByID = this.findBy(_.id)
}
The fix is quite simple:
def * = id ~ entity1 ~ entity2 <> (SomeEntity3.apply _, SomeEntity3.unapply _)
Companion objects of case classes usually are a function from the case class' first argument list to the case class. So if you had
case class Fnord(a: A, b: B, c: C)(d: D)
the Scala compiler would autogenerate the companion object similar to
object Fnord extends ((A, B, C) => Fnord) {
...
}
Now, as soon as you explicitly spell out something about the companion object yourself, the compiler no longer generates the FunctionN
extending thingy. Thus, most of the time it is a good idea to add it yourself. In your case that would mean defining the companion of SomeEntity3
like so:
object SomeEntity3 extends ((Int, Int, Int) => SomeEntity3) {
...
}
There's a (long open) issue for this behaviour, too: https://issues.scala-lang.org/browse/SI-3664
Personally, the partially applied apply
method from the case class does not work with my setup and Slick 3.0.
This however, works, burrowing to the proper tupled
method indirectly:
class WidgetTable(tag: Tag) extends Table[WidgetEntity](tag, "widget_tbl") {
def id = column[Int]("id",O.PrimaryKey)
def foo = column[String]("foo")
override def * = (id,foo) <> ((WidgetEntity.apply _).tupled,WidgetEntity.unapply)
}
See the full details: https://stackoverflow.com/a/38589579/564157