Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

value ~ is not a member of slick.lifted.Rep[Option[Int]]

I have a Scala compile error I have been unable to find any information for. I am using slick 3.0 and am getting a compile error of

value ~ is not a member of slick.lifted.Rep[Option[Int]]

I believe the issue relates to the way I am using an Option to represent my ID field.

I have tried adding id.? to the id field as suggested in this answer but I still get a compilation error in the same vein. Has anything change in slick 3.0?

My code is as follows:

import slick.driver.H2Driver.api._
import scala.concurrent.ExecutionContext.Implicits.global

case class Recipe(id: Option[Int] = None, name: String, instructions: String, ingredients: String)

object AddFixtures {

  class Recipes(tag: Tag) extends Table[Recipe](tag, "recipe") {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def name = column[String]("name")
    def instructions = column[String]("instructions")
    def ingredients = column[String]("ingredients")

    def * = id ~ name ~ instructions ~ ingredients <> (Recipe, Recipe.unapply _)
  }

  val recipes = TableQuery[Recipes]

  val setup = DBIO.seq(
    recipes.schema.create,
    recipes += Recipe(None, "Chicken with Avocado", "Mix it up", "Chicken, Avocado")
  )

  def apply() = {
    val db = Database.forConfig("h2mem1")

    try db.run(setup)
    finally db.close
  }
}
like image 832
GoldenFish Avatar asked Jul 06 '15 14:07

GoldenFish


2 Answers

I think that the problem is that some symbols are not used like before in slick 3.0.0

Take a look here for further problems

in you case the problematic line will be something like this depending what are you going to do, but this should work:

def * = (id, name, instructions, ingredients) <> ((Recipe.apply _).tupled, Recipe.unapply _)

Also you do not need the implicits import

and there is also a problem with your option[Int] parameter: maybe this should be better:

import slick.driver.H2Driver.api._


object SlickStackOverflow extends App {

}

case class Recipe(id: Option[Int] = None, name: String, instructions: String, ingredients: String)

object AddFixtures {

  class Recipes(tag: Tag) extends Table[Recipe](tag, "recipe") {
    def id = column[Option[Int]]("id", O.PrimaryKey, O.AutoInc)
    def name = column[String]("name")
    def instructions = column[String]("instructions")
    def ingredients = column[String]("ingredients")

    def * = (id, name, instructions, ingredients) <> ((Recipe.apply _).tupled, Recipe.unapply _)
  }

  val recipes = TableQuery[Recipes]

  val setup = DBIO.seq(
    recipes.schema.create,
    recipes += Recipe(None, "Chicken with Avocado", "Mix it up", "Chicken, Avocado")
  )

  def apply() = {
    val db = Database.forConfig("h2mem1")

    try db.run(setup)
    finally db.close
  }
}

Or adding .? to the field id, whithout using Option, like we talk in comments, I think that this aproach is better

package org.example

import slick.driver.H2Driver.api._

object SlickStackOverflow extends App {

}

case class Recipe(id: Option[Int], name: String, instructions: String, ingredients: String)

object AddFixtures {

  class Recipes(tag: Tag) extends Table[Recipe](tag, "recipe") {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def name = column[String]("name")
    def instructions = column[String]("instructions")
    def ingredients = column[String]("ingredients")

    def * = (id.?, name, instructions, ingredients) <> ((Recipe.apply _).tupled, Recipe.unapply _)
  }

  val recipes = TableQuery[Recipes]

  val setup = DBIO.seq(
    recipes.schema.create,
    recipes += Recipe(None, "Chicken with Avocado", "Mix it up", "Chicken, Avocado")
  )

  def apply() = {
    val db = Database.forConfig("h2mem1")

    try db.run(setup)
    finally db.close
  }
}
like image 133
anquegi Avatar answered Nov 16 '22 08:11

anquegi


The field1 ~ field2 construct is actually constructing a (field1, field2) tuple under the hood, so as @anquegi points out, simply changing your * projection to use a tuple directly will work.

Alternatively, if you want to use ~ to construct the tuple you can get it back by importing TupleMethods (as ~ was moved out of the normal import scope in Slick 2.0.):

import slick.util.TupleMethods._

See also: Slick 2.0 - update two or more columns

like image 43
Sean Vieira Avatar answered Nov 16 '22 06:11

Sean Vieira