Я не пробовал это, но как насчет черта вы смешиваете в:
trait CommonFields { this: Table[_] =>
def id = column[String]("id", O.PrimaryKey)
def livemode = column[Boolean]("livemode", O.NotNull)
def created = column[DateTime]("created", O.NotNull)
def createdBy = column[Account]("created_by", O.NotNull)
protected common_* = id ~ livemode ~ created ~ createdBy
}
Тогда вы можете сделать:
object AsTable extends Table[(String,Boolean,DateTime,Account,String)]("a_table")
with CommonFields {
def foo = column[String]("foo", O.NotNull)
def * = common_* ~ foo
}
Единственное, что вы» Теперь нужно повторить, это тип элементов.
UPDATE
Если вы хотите сделать объект-отображение и:
- Вы карту к случаю-классы
- Поля в вашем случае классов в том же порядке
Только что:
case class A(
id: String,
livemode: Boolean,
created: DateTime,
createdBy: Account,
foo: String)
object AsTable extends Table[A]("a_table") with CommonFields {
def foo = column[String]("foo", O.NotNull)
def * = common_* ~ foo <> (A.apply _, A.unapply _)
}
Это, по-видимому, наиболее экономичное решение (вместо этого пытается определить *
в CommonFields
и добавить параметр типа). Тем не менее, это требует, чтобы вы изменили все классы case, если ваши поля изменились.
Мы могли бы попытаться смягчить это с помощью состава на случай классов:
case class Common(
id: String,
livemode: Boolean,
created: DateTime,
createdBy: Account)
case class A(
common: Common,
foo: String)
Однако при построении функции картографа, мы (где-то) в конечном итоге, для преобразования кортежей вида:
(CT_1, CT_2, ... CT_N, ST_1, ST_2, ..., ST_M)
CT
Общий вид (известный в CommonFields
)
ST
Конкретный тип (известный в AsTable
)
To:
(CT_1, CT_2, ... CT_N), (ST_1, ST_2, ..., ST_M)
Для того, чтобы передать их в подпрограммы индивидуально преобразования Common
и A
и от их кортежей.
Мы должны сделать это, не зная числа или точные типы либо CT
(при реализации в AsTable
) или ST
(при реализации в CommonFields
). Кортежи в стандартной библиотеке Scala не могут сделать это. Вам нужно будет использовать HLists
, как и для экзамена, предложенного shapeless.
Не вызывает сомнения, стоит ли это усилий.
Основная схема может выглядеть так (без всякого неявного беспорядка, который потребуется). Этот код не будет компилироваться следующим образом.
trait CommonFields { this: Table[_] =>
// like before
type ElList = String :: Boolean :: DateTime :: Account :: HNil
protected def toCommon(els: ElList) = Common.apply.tupled(els.tupled)
protected def fromCommon(c: Common) = HList(Common.unapply(c))
}
object AsTable extends Table[A] with CommonFields {
def foo = column[String]("foo", O.NotNull)
def * = common_* ~ foo <> (x => toA(HList(x)), x => fromA(x) tupled)
// convert HList to A
protected def toA[L <: HList](els: L) = {
// Values for Common
val c_els = els.take[Length[ElList]]
// Values for A
val a_els = toCommon(c_els) :: els.drop[Length[ElList]]
A.apply.tupled(a_els.tupled)
}
// convert A to HList
protected def fromA(a: A) =
fromCommon(a.common) :: HList(A.unapply(a)).drop[One]
}
Используя некоторые больше типа магии, вероятно, можно решить последние две проблемы:
- Поместите
toA
и fromA
в основной признак (с использованием параметров типа в черте, или с помощью абстрактных членов типа)
- Избегайте определения
ElList
явно путем извлечения его из Common.apply
с помощью this technique
Спасибо. Раньше я думал об этом подходе. Но как бы вы справились с определением таблицы. Таблица [(String, Boolean, DateTime, Account, String)] Есть ли способ избежать прикосновения к ней при изменении общих полей? Что делать, если я также привязываю отображение как требование? –
Практически там. Я могу подтвердить, что этот шаблон работает до некоторой степени. Итак, как насчет классов случаев? Предполагая, что мой класс case определен как ... A (foo: Int, B: String, C: String) Для использования сопоставления объектов в его определении должны присутствовать общие поля. Есть ли способ избежать этого? –
@RasputinJones, пожалуйста, см. Обновленный ответ. Отвечая на ваш последний комментарий: вам нужны общие поля где-то в объекте, чтобы снова заполнить их в таблице. – gzm0