さまざまなクエリ コンポーネントを 1 つのクエリに構成するのに問題があります。私の目標は、一連の特性 (SoftDeletable、HasName、SortedByName、WithTimestamps など) を作成して、Table オブジェクトに簡単に組み合わせてその動作を追加できるようにすることです。
理想は次のようになります。
abstract class BaseModel[Tuple <: Product,CaseClass](tableName: String)
extends Table[Tuple](tableName) {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def mapped: MappedProjection[CaseClass, TupleClass]
def allQuery = this.map(_.mapped)
final def all = database.withSession { implicit session: Session =>
allQuery.list()
}
...
}
trait SoftDeletable[Tuple <: Product, CaseClass]
extends BaseModel[Tuple,CaseClass] {
def isActive = column[String]("is_active")
def * = super.* ~ isActive
def allQuery = /* here, I'd like to compose super.allQuery
with a filter that returns rows where isActive is true */
}
trait HasName[Tuple <: Product] extends Table[Tuple] {
def name = column[String]("name")
def * = super.* ~ name
}
trait SortedByName[Tuple <: Product] extends HasName[Tuple {
override def allQuery = super.allQuery /* compose somehow
with (_ <- Query orderBy name */
}
ScalaQuery でこのようなことを行うことはできますか? 主な問題点は次のとおりです。
SoftDeletable.allQuery
でフィルターをきれいに構成し、で並べ替えるにはSortedByName.allQuery
どうすればよいBaseModel.allQuery
ですか?メソッドのサブクラス実装に列を追加することにより
*
、タプル型パラメーターTable
は後者に一致しません - これらの特性が最終的な具象クラスの列タプルに新しい型を段階的に追加する方法はありますか? (あるとは思っていませんが、欠けているものがあればいいのですが)。すべてのトレイトで長いタプル宣言を繰り返す必要がありますが、テーブルに 5 つまたは 6 つの列がある場合、これは非常に扱いにくくなります。次のようなことをしなくても済むように、型メンバーでできることはありますか?
case class Foo class Foos[(Int,Int,Boolean,String), Foo] extends Table[(Int,Int,Boolean,String)] with SoftDeletable[(Int,Int,Boolean,String), Foo] with SortedByName[(Int,Int,Boolean,String), Foo] with HasName[(Int,Int,Boolean,String)] { }
この繰り返しをすべて避けることはできますか?IRC の jesnor からの提案に基づいて、次のようにいくつか回避することができました。
abstract class SoftDeletableBaseModel[TupleClass <: Product, CaseClass](tableName: String)
extends BaseModel[TupleClass, CaseClass](tableName)
with SoftDeletable[TupleClass,CaseClass]
つまり、特定の特性を組み合わせることで、タプル宣言全体を繰り返す必要がなくなります。もちろん、欠点は、さまざまな特性を簡単に混在させることができなくなったことです。この繰り返しを避けるために、特定のサブクラスをたくさん作成する必要があります。別の方法はありますか?
更新:だから、個別の CaseClass と TupleClass 型パラメーターを使用する必要がないことに気付きました。ケース クラスは を実装Product*
しているため、ケース クラス名を Table に渡すだけで、3 の問題は解決します。
trait SoftDeletable[CaseClass] extends BaseModel[CaseClass] { ... }
class Models extends BaseModel[Model]("models") with SoftDeletable[Model] { ... }