Reputation: 31526
I am pretty used to writing the standard slick boiler plate code like this.
Suppose I am creating a table called Foo with columns id and name. We can write
case class Foo(id: Long, name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def id = column[Long]("id")
def name = column[String]("name")
def * = (id, name) <> (Foo.tupled, Foo.unapply)
}
But what if I wanted a single column table where Foo just has a name. The code below does not compile because Now Foo does not have the tupled method anymore.
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = (name) <> (Foo.tupled, Foo.unapply)
}
I found this thread on SO
Scala projections in Slick for only one column
and changed my code to
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("email_address")
def * = (name)
}
but still doesn't compile
Upvotes: 2
Views: 763
Reputation: 2476
I believe previous answers already solve this particular problem. I think however there is one thing worth to add here.
There is nothing in Slick that requires you to use case classes
as an unpacked type
(unpacked type
being kind of your model, in this case Foo
).
In your projection here:
def * = (id, name) <> (Foo.tupled, Foo.unapply)
you could pass whatever two functions you want assuming that:
the first one will create your unpacked type
out of tuple (2+ columns in your projection) or value (1 column projection)
second would create tuple (again in case of 2+ columns in projection) or
value (1 column projection).
It is only convenient that case classes
have such methods generated out of the box (tupled
, apply
, unapply
).
I hope this clarifies that even if you would be lacking such methods it is always possible (at worst case) to e.g. create your functions that would fulfill given requirements.
Upvotes: 2
Reputation: 31526
Found another answer as well
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = name <> (Foo, Foo.unapply)
}
Upvotes: 0
Reputation: 14825
Use Foo.apply _
in case of single parameter. Your code becomes the following
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = (name) <> ((Foo.apply _), Foo.unapply)
}
Explanation:
scala> case class Foo(name: String)
defined class Foo
scala> Foo.apply _
res0: String => Foo = <function1>
In case of single parameter case class Foo.apply _
returns a function1 which is what is required.
But in case of more than one parameter this is not possible so doing .tupled
is expected.
Upvotes: 3