Магистрально-реляционный: ключ ассоциации не будет работать, если он не совпадает с внешним ключом.

Я пытаюсь заставить плагин backbone-relational работать со связью между задачами и сообщениями. (У задачи много сообщений).

Информация взята со стандартного сайта rails/activerecord, который имеет поле task_id в качестве внешнего ключа.

Проблема в том, что магистрально-реляционная система не будет заполнять поле «сообщения» какими-либо сообщениями в модели задачи, если только я не установлю ключ как «task_id» в обратном отношении... но это означает, что при доступе к задаче из Модель сообщения, поле task_id заполняется фактическим объектом задачи, а не целым числом 'task_id', которое перезаписывается.

Я предполагаю, что есть простой способ указать task_id в качестве внешнего ключа, с помощью которого можно определить родительскую задачу, но при этом объект, который представляет этот ключ, помещается в другое поле (например, «задача» в объекте сообщений)... но я не могу понять как. Любые идеи приветствуются. Код ниже

class Backbonescaffolddemo.Models.Task extends Backbone.RelationalModel
  paramRoot: 'task'

  relations: [{
    type: Backbone.HasMany,
    key: "messages",
    relatedModel: "Backbonescaffolddemo.Models.Message",
    collectionType: "Backbonescaffolddemo.Collections.MessagesCollection",
    includeInJSON: true
    reverseRelation: {
      key: "task_id"
      includeInJSON: true
    }
  }]

person PlankTon    schedule 02.01.2012    source источник
comment
Пожалуйста, как вы решили свою проблему? Я открыл следующую проблему на github по той же причине. Благодарю. Внешний ключ, заполненный объектом   -  person antonjs    schedule 05.07.2012


Ответы (2)


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

Пример

В следующем примере предположим, что мы получаем данные из реляционной базы данных старой школы, в которой существует связь «один ко многим» между Monster и Loot_Item. Эта связь выражается внешним ключом Monster_Id в таблице Loot_Item. Давайте также предположим, что наша служба REST не выполняет для нас никаких причудливых вложений данных, поскольку это, кажется, довольно близко соответствует ситуации в вашем вопросе.

keySource

Теперь давайте установим set keySource в мой внешний ключ (Monster_Id) и ключ в имя атрибута, куда я хочу, чтобы фактические данные поступали (скажем, Monster). Если вы запустите отладчик, вы увидите в объекте атрибутов, что на самом деле есть поле под названием Monster, и что оно действительно указывает на данные модели монстра. Эй, круто!

включитьInJSON

Однако, если вы сделаете JSON для этого щенка, угадайте, что? Он поместил все данные монстра в Monster_Id, как вы и не хотели! ГАХ! Мы можем исправить это, установив для includeInJSON значение Monster_Id. Теперь, когда он преобразуется в JSON, он помещает правильный идентификатор обратно в поле Monster_Id при сериализации ваших данных в JSON для отправки на сервер.

Задача решена? Э-э, на самом деле, не обязательно...

ПРЕДОСТЕРЕЖЕНИЕ: все это звучит супер-полезно, но есть одна довольно вопиющая проблема, которую я обнаружил в этом сценарии. Если вы используете механизм шаблонов (например, в Underscore.js), который требует от вас преобразования вашей модели в JSON, прежде чем передавать ее в шаблон, упс — у вас нет доступа к вашим реляционным данным. Увы, JSON, который нам нужен для наших сообщений, не обязательно является тем же JSON, который мы хотим передать в наши шаблоны.

person Tess    schedule 21.05.2012
comment
Пожалуйста, как вы решили эту проблему? Может быть, я что-то пропустил. Я открыл следующий вопрос на github. Внешний ключ, заполненный объектом - person antonjs; 05.07.2012
comment
Smokefoot, СУБД существуют с начала 70-х (по крайней мере). С вычислительной точки зрения это довольно старая школа. Однако это не оценочное суждение об их полезности. Они надежны, варианты их использования очень хорошо изучены, и существует множество технологий, совместимых с ними. К сожалению, многие ДЕЙСТВИТЕЛЬНО НОВЫЕ технологии пренебрежительно относятся к совместимости с должным образом спроектированными реляционными базами данных, и именно поэтому мы полагаемся на сторонние надстройки, такие как Backbone-relational, и почему они ПО-ПРЕЖНЕМУ не очень хорошо решают наши проблемы. - person Tess; 20.10.2012

Если вы хотите, чтобы «task_id» в сообщении JSON был идентификатором, а не полным JSON для задачи, установите «includeInJSON» как свойство идентификатора задачи («task_id»)

class Backbonescaffolddemo.Models.Task extends Backbone.RelationalModel
  paramRoot: 'task'

  relations: [{
    type: Backbone.HasMany,
    key: "messages",
    relatedModel: "Backbonescaffolddemo.Models.Message",
    collectionType: "Backbonescaffolddemo.Collections.MessagesCollection",
    includeInJSON: true
    reverseRelation: {
      key: "task_id"
      includeInJSON: "task_id"
    }
  }]

«Истинное» значение для includeInJSON говорит об использовании полного JSON для связанной модели.

Изменить: перечитав ваш вопрос, я не уверен, что мой ответ относится к вашей проблеме.

Мой первоначальный ответ предназначен для отправки сообщения обратно на сервер, где вы хотите, чтобы JSON был примерно таким:

{
  "message_title": "My Title",
  "message_body": "Blah blah blah...",
  "task_id": 12345
}

Я не уверен, что именно вы ожидаете, но предполагается, что Backbone Relational работает так, что набор сообщений Task будет набором полных моделей, поэтому вы можете перебирать их и передавать их в представления для рендеринга и т. д.

Если вы хотите вывести один из идентификаторов сообщения в шаблоне или что-то в этом роде, вы должны взять «id» модели сообщения:

myTask.get('messages').first().id  ->  returns the first message's id
person Edward M Smith    schedule 02.01.2012
comment
Пожалуйста, как вы решили эту проблему? Может быть, я что-то пропустил. Я открыл следующий вопрос на github. Внешний ключ, заполненный объектом - person antonjs; 05.07.2012