のは、私はBlarg
は、プリミティブ型とプロパティから成ると呼ばれるケースクラスがあるとしましょう:時々、ので、そのすべての列はオプションです
case class Blarg(
x: String,
y: Int
)
Blarg
sは、さまざまなクラスで使用されているがOption[Blarg]
として、場合によってはList[Blarg]
となり、これらのクラスは永続化されます。また、タイプOption[Blarg]
のプロパティを含むOptionalComplexThing
と呼ばれるケースクラスを持っている:
case class OptionalComplexThing(
one: String,
maybeInt: Option[Int],
maybeBlarg: Option[Blarg],
id: Option[Long] = None
)
問題は、適切なサブ突起部を含むデフォルトMappedProjection
を作成する方法です。下記のblarg
MappedProjection
に注目してください。私はblarg
MappedProjection
をColumn
のすべてがOption
であるように変換できるようにしたいと思います。私はこの例をハードコードしたくありません。コンビネータを使ってこれを行う一般的な方法があるはずです。
class _OptionalComplexThings(tag: Tag) extends Table[OptionalComplexThing](tag, "optional_complex_thing") {
def one = column[String]("one")
def maybeInt = column[Option[Int]]("maybe_int") // specifying O.Nullable makes no difference
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
// Blarg fields need to have their lifted types remapped according to MappedProjection usage.
// Notice OptionalComplexThing's maybeBlarg property is an Option[Blarg].
def x = column[String]("x") // want to map to column[Option[String]]("x")
def y = column[Int]("y") // want to map to column[Option[String]]("y")
def blarg = (x, y) <> (Blarg.tupled, Blarg.unapply)
def * = (one, maybeInt, Option(blarg), id) <> (OptionalComplexThing.tupled, OptionalComplexThing.unapply)
/* Error:(23, 46) No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
Required level: scala.slick.lifted.FlatShapeLevel
Source type: (scala.slick.lifted.Column[String], scala.slick.lifted.Column[Option[Int]], Option[scala.slick.lifted.MappedProjection[Blarg,(String, Int)]], scala.slick.lifted.Column[Option[Long]])
Unpacked type: (String, Option[Int], Option[Blarg], Option[Long])
Packed type: Any
def * = (one, maybeInt, Option(blarg), id) <> (OptionalComplexThing.tupled, OptionalComplexThing.unapply)
^*/
}
Here is a a GitHub projectこれは質問を示しています。
これは私が避けたい手作りのアプローチです。このアプローチの問題は、誰かがそれを維持しなければならず、プロジェクトが将来に移るにつれて、人々が退去し、ケースクラスのプロパティが変わるということです。代わりに、コンビネータを使用したいと思います。 Blarg.fromOptionsやcustomUnapplyを手作業で作成することなく、どうすれば同様のことが達成できるでしょうか? –