2013-02-05 25 views
15

SLICK 1.0.0-RC2を使用しています。私は私が持っている理事ケースクラスを再定義しようとしています私のPlayアプリケーションの形で便利総局ケースクラスを作成するにはSERVICEAREASLICKケースクラスで使用するための双方向1対多リレーションシップの定義方法

case class Directorate(dirCode: String, name: String) 

object Directorates extends Table[Directorate]("DIRECTORATES") { 

    def dirCode = column[String]("DIRECTORATE_CODE", O.PrimaryKey) 

    def name = column[String]("NAME") 

    def * = dirCode ~ name <> (Directorate, Directorate.unapply _) 
} 

case class ServiceArea(areaCode: String, dirCode: String, name: String) 

object ServiceAreas extends Table[ServiceArea]("SERVICE_AREAS") { 

    def areaCode = column[String]("AREAE_CODE", O.PrimaryKey) 

    def dirCode = column[String]("DIRECTORATE_CODE") 

    def name = column[String]("NAME") 

    def directorate = foreignKey("DIR_FK", dirCode, Directorates)(_.dirCode) 

    def * = areaCode ~ dirCode ~ name <> (ServiceArea, ServiceArea.unapply _) 
} 

との多くの関係に以下の2つの表理事と理事1つがあるSERVICEAREAを定義していますそのDirectorateに関連するServiceAreasのSeq

case class Directorate(dirCode: String, name: String, serviceAreas: Seq[ServiceArea]) 

私の問題はDirectorateテーブル投影になりました。私は

def * = dirCode ~ name ~ serviceAreas <> (Directorate, Directorate.unapply _) 

ような何かを試すことができますが、serviceAreasは一方向にしか行くように、これは動作しないことができないように

def serviceAreas = (for { a <- ServiceAreas 
         if (a.dirCode === dirCode) 
        } yield (a)).list map { 
         case t: ServiceArea => t 
        } 

:私は、総局のメソッドを作成しようとしました。

Directorateケースクラスが有用なドメインオブジェクトであるため、関連するServiceAreasを含むことができるはずです。

Directorateテーブルの投影が機能するように、逆の関係をどのようにトラバースする必要があるのでしょうか。

答えて

15

私は、よりエレガントな解決策があると確信しているが、これはトリックを行う必要があります:ケースクラスにserviceAreasメソッドを追加するために多くの意味があります

import scala.slick.driver.H2Driver.simple._ 
import Database.threadLocalSession 

object SlickExperiments2 { 

    Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession { 

    (Directorates.ddl ++ ServiceAreas.ddl).create 

    case class Directorate(dirCode: String, name: String) { 
     def serviceAreas: Seq[ServiceArea] = (for { 
     a <- ServiceAreas 
     if (a.dirCode === dirCode) 
     } yield (a)).list 
    } 

    object Directorates extends Table[Directorate]("DIRECTORATES") { 

     def dirCode = column[String]("DIRECTORATE_CODE", O.PrimaryKey) 

     def name = column[String]("NAME") 

     def * = dirCode ~ name <> (Directorate, Directorate.unapply _) 
    } 

    case class ServiceArea(areaCode: String, dirCode: String, name: String) 

    object ServiceAreas extends Table[ServiceArea]("SERVICE_AREAS") { 

     def areaCode = column[String]("AREAE_CODE", O.PrimaryKey) 

     def dirCode = column[String]("DIRECTORATE_CODE") 

     def name = column[String]("NAME") 

     def directorate = foreignKey("DIR_FK", dirCode, Directorates)(_.dirCode) 

     def * = areaCode ~ dirCode ~ name <> (ServiceArea, ServiceArea.unapply _) 
    } 

    Directorates.insert(Directorate("Dircode", "Dirname")) 

    ServiceAreas.insertAll(ServiceArea("a", "Dircode", "A"), ServiceArea("b", "Dircode", "B")) 

    val sa = (for{ 
    d <- Directorates 
    } yield d).list map { case t: Directorate => t.serviceAreas} 

    println(sa) 
    }            
//> List(List(ServiceArea(a,Dircode,A), ServiceArea(b,Dircode,B))) 
} 
+1

感謝。これは、一対多の関係の逆の側面を横切る方法のように見えます。 –

+0

ニース!私はこのアプローチを考慮しなかった。しかし、私には、事務局のケースクラス( 'case t:ServiceArea => ServiceArea(t.areaCode、t.dirCode、t.name)')のServiceAreaの構築が嫌になります。すでに 'ServiceAreas'に存在する構造マッピングを活用する方法はありますか? –

+0

@JonathanWilsonまあ、そのコードの一部はカットアンドペーストの残骸でした。自動生成されたキーでは、IDなしでクラスを構築する必要があり、その行はおそらくそのような場所から来たと考えられます。ありがとうございました - 私はそれを削除しました;-) – Jack

関連する問題