Foreign key populated with an object

落爺英雄遲暮 提交于 2019-12-22 04:05:51

问题


I would like to make a relation between two models User and Task using backbone-relational.

The relation between the two models is the following:

taskModel.creator_id = userModel.id   

// TaskModel
var TaskModel = Backbone.RelationalModel.extend({

    relations: [
        {
            type: Backbone.HasOne,
            key: 'creator',
            keySource: 'creator_id',
            relatedModel: Users
        }
    ],

    // some code
});

// Task collection
var TaskCollection = Backbone.Collection.extend({

    model: TaskModel,

    // some code

});

// User Model
var User = Backbone.RelationalModel.extend({
    // some code
});

Actually the problem is in the collection.models, please see the attached images:

Please check this jsfiddle: http://jsfiddle.net/2bsE9/5/

var user = new User(),
    task = new Task(),
    tasks = new Tasks();

task.fetch();
user.fetch();
tasks.fetch();

console.log(user.attributes, task.attributes, tasks.models);

P.S.:

Actually I am using requireJs to get the UserModel, so I cannot include quotes in relatedModel value.

define([
    'models/user',
    'backbone',
    'relationalModel'
], function (User) {
    "use strict";

    var Task = Backbone.RelationalModel.extend({
        relations: [
            {
                type: Backbone.HasOne,
                key: 'creator',
                keySource: 'creator_id',
                relatedModel: User
            }
        ],
    });
);

回答1:


Edit 2:

http://jsfiddle.net/2bsE9/13/

I updated the jsfiddle to reflect the changes I suggested below. As long as you are calling toJSON on your task, what gets to the server is a json object with the creator_id property set to the actual id of the user. The keyDestination here is redundant as the documentation states it is set automatically if you use keySource.

Edit:

https://github.com/PaulUithol/Backbone-relational#keysource

https://github.com/PaulUithol/Backbone-relational#keydestination

https://github.com/PaulUithol/Backbone-relational#includeinjson

The combination of the three above might solve your issue.

var Task = Backbone.RelationalModel.extend({
    relations: [
        {
            type: Backbone.HasOne,
            // The User object can be accessed under the property 'creator'
            key: 'creator',
            // The User object will be fetched using the value supplied under the property 'creator_id'
            keySource: 'creator_id',
            // The User object will be serialized to the property 'creator_id'
            keyDestination: 'creator_id',
            // Only the '_id' property of the User object will be serialized
            includeInJSON: Backbone.Model.prototype.idAttribute,


            relatedModel: User
        }
    ],
});

The documentation also states that the property specified by keySource or keyDestination should not be used by your code. The property cannot be accessed as an attribute.

Please try this and comment if that fixes your issue.

Btw, here is a nice blog post that uses backbone-relational end to end. http://antoviaque.org/docs/tutorials/backbone-relational-tutorial/




回答2:


Edit

Updated jsfiddle

The problem is that Backbone-Relational explicitly deletes the keySource to 'prevent leaky abstractions'. It has a hardcoded call to unset on the attribute, in Backbone-Relational:

// Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
if ( this.key !== this.keySource ) {
    this.instance.unset( this.keySource, { silent: true } );
}

You will need to overwrite the unset method in your Task model:

var Task = Backbone.RelationalModel.extend({
    urlRoot: ' ',

    relations: [
        {
            type: Backbone.HasOne,
            key: 'creator',
            relatedModel: User,
            keySource: 'creator_id'
        }
    ],

    unset: function(attr, options) {
        if (attr == 'creator_id') {
          return false;
        }

        // Original unset from Backbone.Model:
        (options || (options = {})).unset = true;
        return this.set(attr, null, options);
     },

    sync: function (method, model, options) {
        options.success({
            id: 1,
            name: 'barTask',
            creator_id: 1
        });
    }
});

Obvious problems with this approach are that you will need to modify your code if either Backbone changes its Backbone.Model.unset method or Backbone-Relational changes its keySource behavior.



来源:https://stackoverflow.com/questions/11346777/foreign-key-populated-with-an-object

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