(不是这样)Slick 3.1中的高级映射投影

时间:2015-11-09 21:15:02

标签: scala slick

我正在做R& D我们是否应该使用Scala 2.11 / Play 2.4 / Slick 3.1堆栈来推出新应用。几年前我做了一些Scala编程,并将它作为我最喜欢的小型个人项目语言,但高级概念对我来说仍然是一个谜。

在阅读Matt Handler撰写的this博客文章后,我想在我的PoC应用程序中复制此行为,但我遇到了一些问题。

case class BaseModel[A] (id: Long, model: A)

object BaseModel {
  import scala.language.implicitConversions
  implicit def toModel[A](modelWithId: BaseModel[A]): A = modelWithId.model
}

case class Ingredient(name: String, description: String)

class IngredientsTable(tag: Tag) extends Table[BaseModel[Ingredient]](tag, "ingredients") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def description = column[String]("description")

  def * = (id, name, description) <> ??? // ((BaseModel[Ingredient].apply _).tupled, BaseModel[Ingredient].unapply)
}

我的问题是我应该放置什么而不是???作为注释,pard因为明显的原因不起作用?我知道我需要在那里创建一个自定义的Slick形状,所以它的盒子/ unboxes包含模型val但是我应该怎么做(光滑的文档在这个问题上没有太大帮助)?

我尝试基于this answer做类似的事情,但它给了我编译错误,因为我从早期的Slick版本中看到了这一点,显然我不明白这里发生了什么。

def * = (id, name, description) <> (
    (id, name, description) => BaseModel[Ingredient](id, Ingredient(name, description)),
    (f: BaseModel[Ingredient]) => Some((f.id, f.name, f.description))
  )

希望我正在寻找更自动的东西(在BaseModel中覆盖tupled,unapply?)但是任何工作和任何帮助都会受到赞赏。即使是指向正确位置的RTFM。

编辑: JimN提出了一个有效的答案,但在创建每个这样的映射时需要相当多的样板。你能否提出一个能够最大限度减少样板量的答案?

以下是IngredientsTable添加的内容:

def toBaseModel(id: Long, name: String, description: String): BaseModel[Ingredient] = {
  BaseModel[Ingredient](id, Ingredient(name, description))
}

def fromBaseModel(m: BaseModel[Ingredient]): Option[(Long, String, String)] = {
  Some((m.id, m.name, m.description))
}

def * = (id, name, description) <> ((toBaseModel _).tupled, fromBaseModel)

1 个答案:

答案 0 :(得分:1)

这为我编译:

def * = (id, name, description) <> ((toBaseModelIngredient _).tupled, fromBaseModelIngredient)

... 

def toBaseModelIngredient(id: Long, name: String, description: String): BaseModel[Ingredient] = ??? // implement this
def fromBaseModelIngredient(m: BaseModel[Ingredient]): Option[(Long, String, String)] = ??? // implement this