異なるクエリコンポーネントを1つのクエリにまとめるのに問題があります。私の目標は、テーブルオブジェクトに単純にミックスインしてその動作を追加することができる一連の特性(SoftDeletable、HasName、SortedByName、WithTimestampsなど)を作成することです。再利用可能な特性を作成するためにScalaQueryでクエリを作成するにはどうすればよいですか?
理想的には、次のようになります。
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
でフィルタを構成し、BaseModel.allQuery
とSortedByName.allQuery
でソートできますか?*
メソッドのサブクラス実装で列を追加することで- 、
すべての特性で長いタプル宣言を繰り返す必要があります。これは、表に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)] { }
Table
なし後者試合にタプル型パラメータは - 列が究極の具体的なクラスにタプルにインクリメンタルに新しいタイプを追加するために、これらの特性のための方法は何ですか? (私はそこにいるとは思っていませんが、私が紛失しているものがあればいいと思います)。
は私がすべてのこの繰り返しを避けることができます:私のような事をすることを避けるためにタイプのメンバーで行うことができるものはありますか? IRC上jesnorからの提案に基づいて、私はそうのように、このの一部を回避することができました。つまり
abstract class SoftDeletableBaseModel[TupleClass <: Product, CaseClass](tableName: String)
extends BaseModel[TupleClass, CaseClass](tableName)
with SoftDeletable[TupleClass,CaseClass]
、一緒に特定の特徴を組み合わせることで、私は、全体のタプル宣言を繰り返す必要はありません。もちろん、さまざまな形質の混合が容易ではないという欠点があります。この繰り返しを避けるために、たくさんの特定のサブクラスを作成する必要があります。別の方法がありますか?
更新:私は、別のCaseClassとTupleClassタイプのパラメータを使用する必要がないことに気付きました。ケースクラスはProduct*
を実装しているので、あなただけの3で問題を解決して表へのケースクラス名、渡すことができます:あなたの問題は、唯一の並べ替えを追加している場合
trait SoftDeletable[CaseClass] extends BaseModel[CaseClass] { ... }
class Models extends BaseModel[Model]("models") with SoftDeletable[Model] { ... }
答えはそれ自体ではありませんが、両方の特性に対して列を返すテーブル型から関数を作成し、それらを結合すると(f1、f2)=>(t:table.type) =>((trait1col2、trait1col2)、(trait2col1、trait2col2))))と同じになるmap.mapに渡すことができる関数があります。 。 – nafg
Btw私はこの問題の一部に取り組んでいます:http://stackoverflow.com/questions/11408072/trouble-getting-scala-type-inference-to-work – nafg