Skip to content

Create many-to-many relationships with document references #1

@bartlenaerts

Description

@bartlenaerts

A little change to the MongoSaveHandler makes it possible to create many-to-many relationships with document references.

(I'm not addressing the best practice of MongoDb many-to-many relationships with document references here. As long as you don't create thousands of document references I believe this wouldn't be an issue. In the example on http://docs.mongodb.org/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/ the publisher O'Reilly would have millions of books which will likely cause problems. It is stated: "If the number of books per publisher is small with limited growth, storing the book reference inside the publisher document may sometimes be useful.")

Assume you have an entity Hero which can have multiple Powers. Each entity is a separate Collection in MongoDb. (The full business logic is describer here: http://www.breezejs.com/documentation/presenting-many-many.)

JSON documents for the Powers would be:
{ _id: ObjectId(53c8da213719651618000001), name: "Super Strong" }
{ _id: ObjectId(53c8da213719651618000002), name: "Can Fly" }

A JSON document for the Hero would be:
{ _id: ObjectId(53c8da213719651618000000), name: "Superman", powerIds: [ObjectId(53c8da213719651618000001), ObjectId(53c8da213719651618000002)] }

In Angular the Powers for a Hero can be selected by means of a html select:
<select multiple ng-model="vm.hero.powerIds" ng-options="power.id as power.name for power in vm.powers"></select>
where vm.powers is the array of Powers and vm.hero our Hero normally obtained by Breeze.

The metadata for these entities is the following:

{
    name: 'Hero',
    dataProperties: {
        id: { type: 'MongoObjectId' },
        name: { required: true },
        powerIds: { type: 'MongoObjectId' }
    }
},
{
    name: 'Power',
    dataProperties: {
        id: { type: 'MongoObjectId' },
        name: { required: true }
    }
}

(It would probably be nicer and more correct if you could write something like powerIds: { type: 'MongoObjectIdArray' } but it works this way anyway.)

Loading of the powerIds array already works out of the box, but for saving the MongoSaveHandler needs to be changed a little bit.

On line 280 of the MongoSaveHandler replace the code with:

if (Array.isArray(val)) {
    entity[dp.name] = new Array();
    val.forEach(function(item) { entity[dp.name].push(ObjectID.createFromHexString(item)); });
}
else {
    entity[dp.name] = ObjectID.createFromHexString(val);
}

This enhancement removes the need of an HeroPowerMap entity as described by Ward Bell on http://www.breezejs.com/documentation/presenting-many-many.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions