Общий AutoIncInsert в гладком

Допустим, я хочу иметь столбец идентификатора во всех моих классах case, которые я буду использовать с slick:

abstract class BaseEntity(val _id:Option[Long])
case class SomeEntity(id:Option[Long],value:String) extends BaseEntity(id)

Теперь определим абстрактный класс для схемы и реальной схемы:

  abstract class BaseScheme[A  <: BaseEntity](tag:Tag,name:String) extends Table[A](tag,name) {
    def id = column[Long]("ID",O.PrimaryKey,O.AutoInc)
  }
  class SomeEntityScheme(tag:Tag) extends BaseScheme[SomeEntity](tag,"SOME_NAME") {
    def value = column[String]("value",O.NotNull)
    def * = (id.?,value) <> (SomeEntity.tupled,SomeEntity.unapply)
  }

  val someEntitiesTable = TableQuery[SomeEntityScheme]

Теперь, поскольку я подумал, что мне наскучило писать метод AutoIncInsert, я создам общий, и это тот момент, когда я потерпел неудачу:

 object BaseScheme {
     def autoIncInsert[T <: BaseScheme[_]] (t : TableQuery[T]) = t returning t.map(_.id) into {case (p,id) => p.copy(id = Some(id))}
  }

и, конечно же, вывод проблемы:

[error] /home/tomaszk/Projects/4.4/mCloud/application/service-execution/execution-provisioning-model/src/main/scala/pl/mlife/mcloud/provisioning/database/schemes/ExcludingServicesScheme.scala:48: could not find implicit value for evidence parameter of type scala.slick.ast.TypedType[T#TableElementType]
[error]      def remap[T <: BaseScheme[_]] (t : TableQuery[T]) = t returning t.map(_.id) into {case (p,id) => p.copy(id = Some(id))}
[error]                                                                                                       ^
[error] one error found

person almendar    schedule 12.05.2014    source источник


Ответы (1)


Я могу быть возможен с вашим подходом, у меня недостаточно знаний, чтобы сказать, что это невозможно, но это звучит немного подозрительно и слишком сложно. Я использовал тот же подход, который использовал здесь, то есть определить метод, который принимает T#TableElementType (это будет объект строки) и объект TableQuery и выполняет некоторые общие операции:

def autoIncInsert[T <: BaseScheme[_]](row: T#TableElementType, tableReference: TableQuery[T])(implicit s: Session) = {
  (tableReference returning tableReference.map(_.id)) += row
}

Тогда как тип T вы должны пройти SomeEntityScheme класс.

На мой взгляд, это должно решить вашу проблему более простым и понятным способом.

person Ende Neu    schedule 12.05.2014
comment
У меня есть большой талант иногда разрабатывать слишком сложные решения ;). Спасибо за помощь. Это было именно то, что мне было нужно. - person almendar; 14.05.2014