Я использую Slick
для отображения класса case для таблиц. В определенных классах классов мне нужно иметь дополнительное поле, которого нет в таблице базы данных. Это значение поля будет обновляться на основе некоторых условий ведения бизнеса. Однако я не могу этого сделать, поскольку класс case и slick table должны иметь одинаковые поля.
В java
с Hibernate
это же было достигнуто с @Transient
аннотации @Transient
. Как я могу решить эту проблему? Я связал, добавив @transient
аннотацию в поле класса case. Но на графическом изображении отображаются ошибки компиляции.
Как насчет этого?
case class Container(name: String, width: Float, height: Float, isApproved: Boolean)
val c: Container = ...
val approvedContainer = c.copy(isApproved=true)
И в Slick
...
def * = (name, width, height, false) <> (Container.tupled, Container.unapply)
...
Я не пробовал это, и есть вероятность, что вы столкнетесь с проблемами вставки с вышеуказанным, с которыми вы можете работать или нет.
Другой способ сделать это:
case class Container(name: String, width: Float, height: Float)(val isApproved: Boolean)
object Container{
def applyFunction = (Container.apply _).tupled
def approve(c: Container) = applyFunction(Container.unapply(c).get)(true)
def createNonApproved = (t: (String, Float, Float)) => applyFunction(t)(false)
}
И в Slick
...
def * = (name, width, height, false) <> (Container.createNonApproved, Container.unapply)
...
Имейте в виду, что равенство классов case сравнивает только первый список аргументов.
scala> Container("foo",1,2)()
res2: Container = Container(foo,1.0,2.0)
scala> Container.approve(res2)
res3: Container = Container(foo,1.0,2.0)
scala> res2 == res3
res4: Boolean = true
scala> res2.isApproved
res5: Boolean = false
scala> res3.isApproved
res6: Boolean = true
Иметь ту же проблему, решаемую с помощью этого кода:
case class Container(name: String, width: Float, height: Float, isApproved: Boolean)
class Containers(tag: Tag) extends Table[Container](tag, "CONTAINERS") {
def name = column[String]("NAME", O.PrimaryKey)
def width = column[Float]("WIDTH")
def height = column[Float]("HEIGHT")
def create = (name: String, width: Float, height: Float) =>
Container(name, width, height, isApproved = false)
def destroy(container: Container) =
Some((container.name, container.width, container.height))
def * = (name, width, height) <> (create.tupled, destroy)
}
Вы пробовали это?
case class Container(name: String, width: Float, height: Float, condition: Boolean)
class Containers(tag: Tag) extends Table[Container](tag, "CONTAINERS") {
def name = column[String]("NAME", O.PrimaryKey)
def width = column[Float]("WIDTH")
def height = column[Float]("HEIGHT")
def applyBusinessCondition(): Boolean = ...
def * = (name, width, height, applyBusinessCondition()) <> (Container.tupled, Container.unapply)
}
Я думаю, вы могли бы использовать функцию внутри или вне класса Containers и называть ее в * проекции таблицы. Вы также можете установить условие False внутри определения таблицы и впоследствии изменить его.
Я не пробовал решение @jvican. Я попробую это. Но я решил это по-другому, не изменяя поля классов case и slick mapping tables.
Я создал признак
trait Approvable[TId <:AnyVal]{
var isApproved: Boolean = false
}
Затем я смешал класс в своем классе с Approvable
признаком. После проверки состояния бизнеса я обновляю поле isApproved с истинным/ложным.