2016-08-05 26 views
1

Meine generische Frage ist, wenn Sie ein Datamodell so etwas wie A (1) -> B (viele) -> C (viele) -> D (viele) haben und Sie wollen raus Objekte von D, aber Sie haben nur Kriterien für A, wie können Sie das tun?Bookshelf Query Join multiple Tabellen mit, wo Kriterien

Besonderheiten hier:

const Contact = bookshelf.Model.extend({ 
    sites: function() { 
    return this.hasMany(Site); 
    }, 
}); 

const Contacts = bookshelf.Collection.extend({ 
    model: Contact, 
}); 

const Site = bookshelf.Model.extend({ 
    siteAttendances: function() { 
    return this.hasMany(SiteAttendance); 
    }, 
    siteSupervisor: function() { 
    return this.belongsTo(Contact); 
    }, 
}); 

const Sites = bookshelf.Collection.extend({ 
    model: Site, 
}); 

const SiteAttendance = bookshelf.Model.extend({ 
    site: function() { 
    return this.belongsTo(Site); 
    }, 
    incidents: function() { 
    return this.hasMany(Incident); 
    }, 
}); 

const SiteAttendances = bookshelf.Collection.extend({ 
    model: SiteAttendance, 
}); 

const Incident = bookshelf.Model.extend({ 
    siteAttendance: function() { 
    return this.belongsTo(SiteAttendance); 
    } 
}); 

const Incidents = bookshelf.Collection.extend({ 
    model: Incident, 
}); 

Ich habe einen Kontakt-ID (A-Objekt) bekommen, aber ich mag Objekte, die Vorfälle (D-Objekt) und ich frage mich sind, kann ich dies tun, mit nur Bücherregal. js? Für jeden Kontakt gibt es VIELE Sites und Site Attendances, aber nur wenige Incidents. Eine Kontakt-ID wird viele Sites ergeben, also könnte es einen Weg geben, von Incident zur Site mit einer through zu gehen, aber ich konnte das nicht zum Laufen bringen. Ich glaube nicht, dass ich bei Contact anfange und withRelated den ganzen Weg hinunter mache, ist der richtige Ansatz (da es so viele von Site und SiteAttendance gibt), aber ich könnte falsch liegen.

Antwort

0

Schlecht können Sie through nicht für tiefe Beziehungen verwenden. Und withRelated Option, wird 3 Abfragen zum Zurückholen der Kontakt incidents. Wenn Sie nicht interessiert, wird withRelated: "sites.siteAttendances.incidents" Sie speichern.

+0

Das habe ich mir gedacht. Gibt es für solche Dinge einen Konsens darüber, dass man nicht mit Bücherregal knex kleben sollte? – ricka

0

Ich habe genau das gleiche Problem und ich fragte mich auch, ob es ein "Bookshelf-y" Weg, es zu tun ist. Ich habe etwas Knex-basierten Code implementiert und es funktioniert. Das heißt, es gibt eine einzige SELECT-Anweisung mit den angegebenen Joins aus.

Er übersetzt zu Ihrem Beispiel etwa wie folgt:

const exampleVal = Incident.forge(); 
    const toSiteAt = exampleVal.siteAttendance(); 
    const incTable = toSiteAt.relatedData.parentTableName; 
    const saTable = toSiteAt.relatedData.targetTableName; 
    const saKey = toSiteAt.relatedData.targetIdAttribute; 
    const forKeySA = toSiteAt.relatedData.foreignKey; 

    const toSite  = toSiteAt.site(); 
    const siteTable = toSite.relatedData.targetTableName; 
    const siteKey = toSite.relatedData.targetIdAttribute; 
    const forKeyS = toSite.relatedData.foreignKey; 

    const toContact = toSite.siteSupervisor(); 
    const contctTable = toContact.relatedData.targetTableName; 
    const contctKey = toContact.relatedData.targetIdAttribute; 
    const forKeyC  = toContact.relatedData.foreignKey; 

    return Incident.query(qb => { 
    qb.innerJoin(saTable,  `${incTable}.${forKeySA}`, `${saTable}.${saKey}`) 
     .innerJoin(siteTable, `${saTable}.${forKeyS}`, `${siteTable}.${siteKey}`) 
     .innerJoin(contctTable, `${siteTable}.${forKeyC}`, `${contctTable}.${contctKey}`) 
     .whereIn(`${contctTable}.id`, myContactId); // <1> 
    }).fetchAll(); 

< 1> Hier ist Ihre Contact ID

Frage an alle anderen: Gibt es eigentlich etwas mehr "Bücherregal-y" Art und Weise zu löse das?

+0

Ich schätze es sehr, dass dies eine weitere Aufgabe ist, zumal es sich hier nur um eine Abfrage handelt, um die benötigten Informationen abzurufen. Vielleicht, weil niemand diese Antwort gesehen hat, lohnt es sich, mit Ihrer Lösung eine neue Frage zu stellen und nach dem besten "Bücherregal" zu fragen? – ricka