2015-09-08 15 views
9

के परिणाम प्राप्त मैं इस तरह कई संबंध सेटअप करने के लिए एक बहुत है:स्लिक दो तालिकाओं में शामिल होने और दोनों

व्यक्ति < -> PersonField < -> फील्ड

अब मैं न केवल सभी क्षेत्रों क्वेरी करना चाहते हैं एक व्यक्ति (मैं ऐसा कर सकता हूं), लेकिन एक व्यक्ति के क्षेत्र के साथ PersonField का एक जोड़ा संस्करण। (मैं क्वेरी/साथ ही धुरी/इंटरमीडिएट तालिका "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] 
} 

अब किसी व्यक्ति के सभी क्षेत्रों से पूछताछ करने के लिए मेरे पास थोड़ा सहायक श्रेणी है:

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 के प्रत्येक क्षेत्र कंसोल के लिए मुद्रित हो जाता है। एक जादू की तरह काम करता है।

बात यह है कि, मैं भी व्यक्ति फ़ील्ड (फ़ील्ड के साथ) प्राप्त करना चाहता हूं!

तो मैं निम्न परिवर्तन (दूसरों के बीच बात नहीं बनी है, जो मुझे याद नहीं)

की कोशिश की में व्यक्ति:

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) // यहां कोई फ्लैटमैप नहीं है!

तो getFields (पी: व्यक्ति) इस तरह दिखता है:

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

क्या आपने किसी व्यक्ति, फ़ील्ड और सही आईडी वाले व्यक्ति को इंजेक्ट करने के लिए यूनिट परीक्षण के साथ प्रयास किया था और यह देखते हुए कि क्वेरी का कोई परिणाम नहीं मिलता है? – Edmondo1984

+0

मैंने इसे मैन्युअल रूप से और सत्यापित किया कि तालिकाएं सैनी (अपेक्षित के रूप में) हैं, इसलिए: आंशिक रूप से हां;) – Sorona

+0

क्या आप पूरी तरह से काम कर रहे गिस्ट दे सकते हैं? – Edmondo1984

उत्तर

2

आप सभी तीन शामिल हो सकते हैं, तो परिणाम

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) 

उपज (मुझे यकीन है कि मुझे मिल गया, ताकि आप केवल उपज हिस्सा संपादित कर सकते हैं कि वास्तव में क्या आप क्वेरी से बाहर निकलने का प्रयास कर रहे थे, नहीं कर रहा हूँ)

संबंधित मुद्दे