【问题标题】:(Not so) advanced mapped projection in Slick 3.1(不是这样)Slick 3.1 中的高级映射投影
【发布时间】:2015-11-09 21:15:01
【问题描述】:

我正在研发是否应该使用 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 形状,以便将模型 val 装箱/取消装箱,但我应该怎么做(Slick 文档在这件事上没有太大帮助)?

我试图根据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 中不适用?)但任何工作和任何帮助都值得赞赏。如果指向正确的地方,即使是 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)

【问题讨论】:

    标签: scala slick


    【解决方案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
    

    【讨论】:

    • 不幸的是它不适合我。我收到以下错误:pastebin.com/R9PtCrg7 我做到了:def toBaseModelIngredient = BaseModel[Ingredient](id, Ingredient(name, description)) def fromBaseModelIngredient = Some((m.id, m.name, m.description)) 我错过了什么吗?
    • Nvm,当然可以。这是我这边的一个愚蠢的错误(留下了一些导致冲突的调试更改)。支持,但不会在接下来的一两天内标记为已回答,因为我希望得到一些更自动的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    相关资源
    最近更新 更多