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

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

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

Проблема в том, что магистральная реляционная система не заполняет поле 'messages' сообщениями в модели Task, если я не установлю ключ как "task_id" в обратном отношении ... но это означает, что при доступе к task из модели Message, поле task_id заполняется фактическим объектом задачи, а не целым числом task_id, которое перезаписывается.

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

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
    }
  }]

Ответы [ 2 ]

3 голосов
/ 22 мая 2012

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

Пример

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

keySource

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

includeInJSON

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

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

CAVEAT : Все это звучит очень полезно, но есть одна довольно вопиющая проблема, которую я обнаружил с этимсценарий.Если вы используете шаблонизатор (такой как в Underscore.js), который требует от вас преобразования вашей модели в JSON, прежде чем передавать ее в шаблон, к сожалению, у вас нет доступа к вашим реляционным данным.Увы, JSON, который мы хотим для наших сообщений, не обязательно является тем JSON, который мы хотим вставить в наши шаблоны.

0 голосов
/ 03 января 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 будет представлять собой коллекцию полных моделей, поэтому вы можете выполнять итерацию по ним и передавать их в представления для визуализации и т. д.

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

myTask.get('messages').first().id  ->  returns the first message's id
...