Implementing a Many-to-Many relationship with Backbone-Relational

天大地大妈咪最大 提交于 2019-12-03 13:51:12

I ended up getting this to work the way I wanted to. The Many-to-Many relationship is maintained in the database but the relationships can only be accessed in my Backbone models in one direction. I decided that the Person models would be stand-alone and the PersonGroup models would have a collection of references to the Person models they are linked to.

The key points here that made everything work were to specify includeInJSON: "ID" and to remove the reverseRelation. This still lets you access the references to the models in JavaScript, but it correctly serializes and deserializes to JSON. The Person models simply don't have access to a navigation property to the Groups they are in, however they can exist in multiple groups just fine.

I simply assumed that using a list of IDs would mandate jumping through hoops to resolve references, but Backbone-relational seems to use the global Backbone model store to resolve references by ID without creating duplicate models. (eg. Three different groups can reference the same Person and only one model is ever created).

var Person = Backbone.RelationalModel.extend(
{
    idAttribute: "ID",
});

var PersonGroup = Backbone.RelationalModel.extend(
{
    idAttribute: "ID",

    relations:
    [
        {
            type: Backbone.HasMany,
            key: "People",
            relatedModel: "Person",
            collectionType: "PersonCollection",
            includeInJSON: "ID",
        },
    ],
});

And here's the rest of the plumbing if it helps anyone.You can define the Backbone.Collections as follows and obtain them through separate API requests:

var PersonCollection = Backbone.Collection.extend(
{
    model: Person,

    url: "/api/person",
});

var PersonGroupCollection = Backbone.Collection.extend(
{
    model: PersonGroup,

    url: "/api/persongroup",
});

var PersonModels = new PersonCollection();

var GroupsModels = new PersonGroupCollection();

this.PersonModels.fetch();

this.GroupsModels.fetch();

this.People = kb.collectionObservable(
    this.PersonModels,
    {
        factories:
        {
            "models": PersonViewModel,
        },
    }
);

this.PersonGroups = kb.collectionObservable(
    this.GroupsModels,
    {
        factories:
        {
            "models": PersonGroupViewModel,
            "models.People.models": PersonViewModel,
        },
    }
);

I included the Knockback.js specific collections for using Knockout.js bindings. Only one ViewModel is created per model so change tracking is propagated through the entire app.

This question is about two months old, nevertheless I would like to share that I ran into similar problems concerning many-to-many relationships when working with Backbone-relational. These problems led to the writing of an own implementation of Backbone relations which support many-to-many relationships without a linking model in between: Backbone-JJRelational

I am answering as one of the authors, but it might be worth to check out.
The JSON you posted in your question, for example, would automatically be deserialized in the following way:
Each PeopleGroups-model has an attribute People which is a Backbone.Collection containing the appropriate People-models and (of course) vice-versa, so the relation can be easily accessed from both sides (without a linking model).
Some concepts of Backbone-JJRelational are similar to Backbone-relational (global model store, for example).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!