user504909
user504909

Reputation: 9549

how to make Option[Int] save in scala slick

I want to save Rescource with foreignkey of Users

case class User(id: Option[Int], name : String)

object Users extends Table[User]("users") {
def id = column[Int]("id", O.PrimaryKey)
def name =  column[String]("name", O.NotNull)
def * = id.? ~ name <> (User, User.unapply _)

def add(user: User)(implicit session: Session) = {
  this.insert(user)
}

def countByName(name: String)(implicit session: Session) = {
  (for {
    user <- Users
    if (user.name === name)
  } yield(user)).list.size
}

}
case class Resource(id: Option[Long] = None, owner: Int, types: String)


object Resources extends Table[Resource]("RESOURCE") {
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def owner = column[Int]("Owner")
def types = column[String]("Type")
def withuser = foreignKey("User_FK", owner, Users)(_.id)

// Every table needs a * projection with the same type as the table's type parameter
def * = id ~ owner ~ types <> (Resource, Resource.unapply _)
}

when I compile the error is:

[error] F:\mysource\play-slick\app\models\Resource.scala:17: overloaded method v
alue <> with alternatives:
[error]   [R(in method <>)(in method <>)(in method <>)(in method <>)(in method <
>)(in method <>)(in method <>)(in method <>)](f: (Long, Int, String) => R(in met
hod <>)(in method <>)(in method <>)(in method <>)(in method <>)(in method <>)(in
method <>)(in method <>), g: R(in method <>)(in method <>)(in method <>)(in met
hod <>)(in method <>)(in method <>)(in method <>)(in method <>) => Option[(Long,
Int, String)])scala.slick.lifted.MappedProjection[R(in method <>)(in method <>)
(in method <>)(in method <>)(in method <>)(in method <>)(in method <>)(in method
<>),(Long, Int, String)] <and>
[error]   [R(in method <>)(in method <>)(in method <>)(in method <>)(in method <
>)(in method <>)(in method <>)(in method <>)](f: ((Long, Int, String)) => R(in m
ethod <>)(in method <>)(in method <>)(in method <>)(in method <>)(in method <>)(
in method <>)(in method <>), g: R(in method <>)(in method <>)(in method <>)(in m
ethod <>)(in method <>)(in method <>)(in method <>)(in method <>) => Option[(Lon
g, Int, String)])scala.slick.lifted.MappedProjection[R(in method <>)(in method <
>)(in method <>)(in method <>)(in method <>)(in method <>)(in method <>)(in meth
od <>),(Long, Int, String)]
[error]  cannot be applied to (models.Resource.type, models.Resource => Option[(
Option[Long], Int, String)])
[error]   def * = id ~ owner ~ types <> (Resource, Resource.unapply _)
[error]                              ^

I think this is the problem of serial the Option[Int], anybody know how to save Option[Int]

Upvotes: 1

Views: 660

Answers (1)

Mike Cialowicz
Mike Cialowicz

Reputation: 10020

Your Resource case class doesn't match your Resources object. You have Int, String, String matching up with a companion object that has Long, Int, String. Change Resources to:

object Resources extends Table[Resource]("RESOURCE") {
    def id    = column[Long]("ID", O.PrimaryKey, O.AutoInc)
    def owner = column[String]("Owner")
    def types = column[String]("Type")

    def withuser = foreignKey("User_FK", owner, Users)(_.id)
}

Also, I recommend changing all your Option[Int] case class id values to Option[Long], to match your objects.

UPDATE:

As user @cvogt mentioned, you also need a .? on the optional fields in your projection, like the following:

def * = id.? ~ owner ~ types <> (Resource, Resource.unapply _)

Upvotes: 2

Related Questions