scalaslick

When overloading `apply` method: Slick error message 'value tupled is not a member of object'


I need an ability to create a User object by providing all the values except id in certain cases, such that the User object takes care of assigning itself an auto-generated value.

For this I have overloaded the apply method in the companion object, like shown below. But this is causing the compile time error: value tupled is not a member of object.

Solutions mentioned on StackOverflow and other blogs aren't working, such as: http://queirozf.com/entries/slick-error-message-value-tupled-is-not-a-member-of-object

case class User(id: Long, firstName: String, lastName: String, mobile: Long, email: String)

object User {
  private val seq = new AtomicLong

  def apply(firstName: String, lastName: String, mobile: Long, email: String): User = {
    User(seq.incrementAndGet(), firstName, lastName, mobile, email)
  }
}

class UserTableDef(tag: Tag) extends Table[User](tag, "user") {

  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def firstName = column[String]("first_name")
  def lastName = column[String]("last_name")
  def mobile = column[Long]("mobile")
  def email = column[String]("email")

  override def * =
    (id, firstName, lastName, mobile, email) <> (User.tupled, User.unapply)

}

Solution

  • The source of your problem is that overloaded apply def.

    tupled does not work with case class's with less than 2 parameters or overloaded apply.

    As far as slick's * (or all) mapping and <> is concerned, it is supposed to be like,

    def * = (tupleMember1, tupleMember2, ...) <> (func1, func2)
    

    Such that,

    So you can provide any function... which meets these requirements.

    case class User(id: Long, firstName: String, lastName: String, mobile: Long, email: String)
    
    object User {
      private val seq = new AtomicLong
    
      def apply(firstName: String, lastName: String, mobile: Long, email: String): User = {
        User(seq.incrementAndGet(), firstName, lastName, mobile, email)
      }
    
      def mapperTo(
        id: Long, firstName: String,
        lastName: String, mobile: Long, email: String
      ) = apply(id, firstName, lastName, mobile, email)
    
    }
    
    class UserTableDef(tag: Tag) extends Table[User](tag, "user") {
    
      def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
      def firstName = column[String]("first_name")
      def lastName = column[String]("last_name")
      def mobile = column[Long]("mobile")
      def email = column[String]("email")
    
      override def * =
        (id, firstName, lastName, mobile, email) <> ((User.mapperTo _).tupled, User.unapply)
    
    }