Внешний ключ, заполненный объектом

Я хотел бы установить связь между двумя моделями User и Task, используя магистрально-реляционную модель.

Связь между двумя моделями следующая:

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
});

На самом деле проблема в коллекции.Модели, смотрите прикрепленные изображения:

Пожалуйста, проверьте этот 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.:

На самом деле я использую requireJs для получения UserModel, поэтому я не могу включать кавычки в значение relatedModel.

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
            }
        ],
    });
);

person antonjs    schedule 05.07.2012    source источник


Ответы (2)


Редактировать 2:

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

Я обновил jsfiddle, чтобы отразить изменения, предложенные ниже. Пока вы вызываете toJSON для своей задачи, на сервер попадает объект json со свойством creator_id, установленным на фактическое id пользователя. keyDestination здесь избыточен, поскольку в документации указано, что он устанавливается автоматически, если вы используете keySource.

Изменить:

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

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

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

Комбинация трех вышеперечисленных может решить вашу проблему.

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
        }
    ],
});

В документации также указано, что свойство, указанное keySource или keyDestination, не должно использоваться вашим кодом. Свойство не может быть доступно как атрибут.

Пожалуйста, попробуйте это и прокомментируйте, если это решит вашу проблему.

Кстати, вот хороший пост в блоге, в котором сквозное использование реляционной магистрали. http://antoviaque.org/docs/tutorials/backbone-relational-tutorial/

person Amith George    schedule 10.07.2012
comment
Вопрос: почему атрибут creator_id отсутствует в tasks.models? - person antonjs; 10.07.2012
comment
Вызывает ли отсутствующий Creator_id проблемы? Вы не можете изменить задачу и вернуть изменения? Я пытаюсь понять, вам просто любопытно или есть определенная проблема. Если есть проблема, может быть, мы можем попытаться решить ее... Если нет, что ж, мы можем подождать кого-то, кто знает больше :) - person Amith George; 10.07.2012
comment
Отсутствие Creator_id является проблемой, когда вы пытаетесь сохранить связанную модель, потому что серверная часть ожидает увидеть Creator_id. - person antonjs; 10.07.2012
comment
@AntoJs, ты смог попробовать? - person Amith George; 11.07.2012
comment
Я просмотрел ваш jsfiddle.net/2bsE9/13, и он работает. В моем localHost использование requireJs не работает. Я пытаюсь понять, в чем проблема, потому что в jsfiddle ее будет сложно воспроизвести. - person antonjs; 11.07.2012
comment
Любопытно, зачем принимать этот ответ и присуждать награду другому? Я знаю, что это разрешено в соответствии с системой вознаграждений, и у них есть свои причины для ее реализации. Тем не менее, я не уверен, что с этим делать. Вы говорите, что, хотя этот ответ работает, вы бы предпочли делать то, что предлагает другой ответ? Если это действительно то, что вы чувствуете, то вы должны отметить это как ответ... - person Amith George; 13.07.2012
comment
Мне жаль. На самом деле я не знаю, почему я назначил награду Танзибу Халили. Потому что я хочу наградить тебя. К сожалению, я не знаю, как отменить награду Танзибу Халили. - person antonjs; 13.07.2012

Изменить

Обновленный jsfiddle

Проблема в том, что Backbone-Relational явно удаляет keySource, чтобы «предотвратить дырявые абстракции». Он имеет жестко запрограммированный вызов unset для атрибута в 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 } );
}

Вам нужно будет перезаписать метод unset в вашей модели Task:

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
        });
    }
});

Очевидные проблемы с этим подходом заключаются в том, что вам нужно будет изменить свой код, если либо Backbone изменит свой Backbone.Model.unset метод, либо Backbone-Relational изменит свое keySource поведение.

person Tanzeeb Khalili    schedule 10.07.2012
comment
На самом деле я использую requireJs для получения модели пользователя. Поэтому я не могу включать кавычки. Я добавлю больше деталей в свой вопрос. - person antonjs; 10.07.2012
comment
В любом случае, что насчет сообщения Relation= d ; no model, key or relatedModel (function (){a.apply(this,arguments)}, "creator", undefined) - person antonjs; 10.07.2012
comment
Хорошо, между вашими комментариями в этом и другом ответах я думаю, что понимаю ваши требования. Обновил мой ответ рабочим решением. - person Tanzeeb Khalili; 12.07.2012