2015-09-08 8 views
9

の結果が得られます。スリックは、2つのテーブルを結合し、私はこのような多くの関係のセットアップに多くを持って、両方の

人< - > PersonField < - >フィールド

は今、私だけでなく、すべてのフィールドを照会します(私はそれを行うことができます)が、PersonFieldとPerson of Fieldの結合バージョンです。 (私は/クエリとしてもピボット/中間テーブル "PersonField" の情報を取得したい!)

パーソン:

case class Person(id: Long, name: String) 
{ 
    def fields = 
    { 
     person <- Persons.all.filter(_.id === this.id) 
     field <- person.fields 
    } yield field 
} 

class Persons(tag: Tag) extends Table[Person](tag, "persons") 
{ 
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc) 
    def name = column[String]("name") 

    def * = (id, name) <> (Person.tupled, Person.unapply) 
    def fields = PersonFields.all.filter(_.personID === id).flatMap(_.fieldFK) 
} 

object Persons 
{ 
    lazy val all = TableQuery[Persons] 
} 

フィールド:

case class Field(id: Long, name: String, description: Option[String]) 

class Fields(tag: Tag) extends Table[Field](tag, "fields") 
{ 
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc) 
    def name = column[String]("name") 
    def description = column[Option[String]]("description") 

    def * = (id, name, description) <> (Field.tupled, Field.unapply) 
} 

object Fields 
{ 
    lazy val all = TableQuery[Fields] 
} 

PersonField:

case class PersonField(id: Long, personID: Long, fieldID: Long, value: String) 

// TODO add constraint to make (personID, fieldID) unique 
class PersonFields(tag: Tag) extends Table[PersonField](tag, "person_field") 
{ 
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc) 
    def personID = column[Long]("person_id") 
    def fieldID = column[Long]("field_id") 
    def value = column[String]("value") 

    def * = (id, personID, fieldID, value) <> (PersonField.tupled, PersonField.unapply) 

    def personFK = foreignKey("person_fk", personID, Persons.all)(_.id) 
    def fieldFK = foreignKey("field_fk", fieldID, Fields.all)(_.id) 
} 

object PersonFields 
{ 
    lazy val all = TableQuery[PersonFields] 
} 

Personのすべてのフィールドを照会するために、少しヘルパークラスがあります:

def getFields(p: Person): Future[Seq[Field]] = 
{ 
    val query = p.fields 
    db.run(query.result) 
} 

だから私は

ヴァルpersonXを行うことができます...

personX.onSuccess 
{ 
    case p: Person => 
    { 
     val fields = helper.getFields(p) 
     fields.onSuccess 
     { 
      case f: Seq[Field] => f foreach println 
     } 
    } 
} 

は今personXの各フィールドは、コンソールに出力されます。魅力のように動作します。

私はPersonFieldも(Fieldと一緒に)取得したいと思います!

だから私は人

を(私は思い出すことができない動作しませんでした他の人の間で、)次のように変更してみました:

def fields = 
{ 
    for 
    { 
     person <- Persons.all.filter(_.id === this.id) 
     field <- person.fields join Fields.all on (_.fieldID === _.id) 
    } yield field 
} 

def fields = PersonFields.all.filter(_.personID === id) //ここにflatMapはありません!

そしてれるGetFields(P:人)次のようになります。

def getFields(p: Person): Future[Seq[(PersonField, Field)]] 

しかし

personX.onSuccess 
{ 
    case p: Person => 
    { 
     val fields = helper.getFields(p) 
     fields.onSuccess 
     { 
      case f: Seq[(PersonField, Field)] => f map(f => println(f._1)} 
     } 
    } 
} 

は私に何も与えないので、私は私の参加が間違っている必要がありますね。しかし、私は間違って何をしているのですか?

+0

ユニットテストで正しいIDを持つ人物、フィールド、人物フィールドを注入して、結果が返されないことを確認しましたか? – Edmondo1984

+0

私はそれを手作業で試してみて、テーブルが正常であることを確認しました:(部分的には;;) – Sorona

+0

完全に機能する要点を教えてください。 – Edmondo1984

答えて

2

あなたはすべての3つ、そして結果を得

for { 
     ((personField, person), field) <- PersonFields.all join Persons.all on (_.personId === _.id) join Fields.all on (_._1.fieldId === _.id) 
     if person.id === this.id 
    } yield (personField, person, field) 

(あなただけの歩留まり部分を編集することができますので、私は、私はあなたがクエリから抜け出すためにしようとしていた正確に何を得たことを確認していない)

に参加することができます
関連する問題