Ember Cli Mirage: адаптер активной модели с JSONAPISerializer

Я на полпути к реализации структуры JSON API (с атрибутами подчеркивания).


Фактическое состояние среды разработки:

Я использую структуру Адаптер активной модели для запроса к серверной части ресурсов и серверной части. ответьте мне структурой JSON API.

В сериализаторе приложений я использую JSONAPISerializer. Я переопределяю методы:

serializeBelongsTo
keyForRelationship
keyForAttribute
serialize
serializeAttribute
serializeHasMany

а для разработки у меня все работает (бэкенд в Rails очень хорошо общается с Ember).


Проблема связана с Ember CLI Mirage и соглашениями (не уверен, есть ли простые решения или мне нужно снова переопределить методы в этом дополнении).

Фактическое состояние с Ember Cli Mirage и тестовой средой:

Я использую import { JSONAPISerializer } from 'ember-cli-mirage';, а затем пытаюсь обработать правильный запрос, а затем преобразовать его в формат JSON API.

Это может работать так:

Адаптер Ember (формат адаптера активной модели — с атрибутами подчеркивания) ---> Сериализатор Mirage должен получить запрос (найти ресурсы, созданные ранее в тестах с ассоциациями), а затем ответить на него в формате JSON API ---> Сериализатор JSON API может перехватить его и залить Ember DS.

На данный момент у меня отсутствует часть, чтобы сериализовать его для всех случаев по стандарту JSON API (с подчеркнутыми атрибутами)

Где я должен выполнить это преобразование, чтобы свести к минимуму переопределение JSONAPISerializer Mirage Serializer.

Я заметил, что есть некоторые помощники, но у меня проблема с объединением этих знаний (http://www.ember-cli-mirage.com/docs/advanced/route-handlers#helpers)

ОБНОВЛЕНИЕ:

Пример структуры из Backend:

{
  "data": {
    "id": "6",
    "type": "first_resource",
    "attributes": {
      "id": 6,
      "my_attribute": "my_attribute"
    },
    "relationships": {
      "second_resources": {
        "data": [
          {
            "id": "16",
            "type": "second_resource"
          }
        ]
      },
      "third_resource_other_type": {
        "data": {
          "id": "1",
          "type": "third_resource"
        }
      },
      "fourth_resource": {
        "data": {
          "id": "1",
          "type": "fourth_resource"
        }
      }
    },
    "links": {
      "fifth_resources": "/api/v1/first_resources/6/fifth_resources"
    }
  },
  "included": [
    {
      "id": "1",
      "type": "fourth_resource",
      "attributes": {
        "id": 1,
        "my_attribute": "my_attribute"
      },
      "links": {
        "sixth_resource": "/api/v1/fourth_resources/1/sixth_resource"
      }
    },
    {
      "id": "16",
      "type": "second_resource",
      "attributes": {
        "id": 16,
        "my_attribute": "my_attribute"
      },
      "relationships": {
        "eighth_resources": {
          "data": []
        }
      },
      "links": {
        "seventh_resources": "/api/v1/second_resources/16/seventh_resources"
      }
    },
    {
      "id": "17",
      "type": "second_resource",
      "attributes": {
        "id": 17,
        "my_attribute": "my_attribute"
      },
      "relationships": {
        "eighth_resources": {
          "data": []
        }
      },
      "links": {
        "seventh_resources": "/api/v1/second_resources/17/seventh_resources"
      }
    },
    {
      "id": "15",
      "type": "second_resource",
      "attributes": {
        "id": 15,
        "my_attribute": "my_attribute"
      },
      "relationships": {
        "eighth_resources": {
          "data": [
            {
              "id": "26",
              "type": "eighth_resource"
            },
            {
              "id": "24",
              "type": "eighth_resource"
            }
          ]
        }
      },
      "links": {
        "seventh_resources": "/api/v1/second_resources/15/seventh_resources"
      }
    },
    {
      "id": "26",
      "type": "eighth_resource",
      "attributes": {
        "id": 26,
        "my_attribute": "my_attribute"
      }
    }
  ]
}

ОБНОВЛЕНИЕ 2

структура из ответа миража:

data: {
  attributes: {
    my_attribute: 'my_attribute',
    second_resource_ids: [36, 37],
    fifth_resource_ids: []
  },
  id: 11,
  relationships: {
    third_resource_other_type: {data: null}
    fourth_resource: {data: null}
    second_resources: {data: []}
  },
  type: "first_resources"
}

ресурсы в тестах:

server.create('second-resource', {
  id: 36,
  first_resource_id: '11',
  my_attribute: "my_attribute"
});

server.create('eighth-resource', { 
  id: 140,
  second_resource_id: 37
});

server.create('eighth-resource', {
  id: 141,
  second_resource_id: 37
});

server.create('second-resource', {
  id: 37,
  first_resource_id: '11',
  eighth_resource_ids: [140, 141]
});

server.create('first-resource', {
  id: 11,
  second_resource_ids: [36, 37]
});

модель first_resource в Mirage:

export default Model.extend({
  third_resource_other_type: belongsTo(),
  fourth_resource: belongsTo(),
  fifth_resources: hasMany(),
  second_resources: hasMany()
});

person Hubert Olender    schedule 10.03.2019    source источник
comment
Не могли бы вы опубликовать обновление с простым примером полезной нагрузки JSON, поступающей с вашего сервера Rails, а также как выглядит соответствующий ответ Mirage для той же конечной точки?   -  person Sam Selikoff    schedule 10.03.2019
comment
@SamSelikoff обновил пример ответа от моего бэкэнда   -  person Hubert Olender    schedule 10.03.2019


Ответы (1)


Давайте попробуем сосредоточиться на одном отношении, так как в вопросе, который вы разместили, многое происходит. Мы посмотрим на second-resource.

Похоже, что Mirage отправляет обратно second_resource_ids под ключом attributes первичных данных first_resource в полезной нагрузке JSON:API. Это говорит мне о том, что Mirage считает second_resource_ids атрибутом first_resource, хотя на самом деле это отношение.

Предполагая, что ваши модели и отношения настроены правильно, вам необходимо настроить способ создания данных в Mirage.

Если вы взглянете на раздел Associations документа Определение Путеводитель по маршрутам, вы увидите следующее сообщение:

База данных Mirage использует camelCase для всех атрибутов модели, включая внешние ключи (например, authorId в приведенном выше примере).

Прямо сейчас вы делаете это:

server.create('second-resource', {
  id: 36,
  first_resource_id: '11',
  my_attribute: "my_attribute"
});

server.create('first-resource', {
  id: 11,
  second_resource_ids: [36, 37]
});

Но с точки зрения Mirage вам нужно использовать camelCase идентификаторов или просто передавать отношения, чтобы настроить их правильно. Что-то вроде этого:

let firstResource = server.create('first-resource', {
  id: 11
});

server.create('second-resource', {
  id: 36,
  firstResource,
  myAttribute: "my_attribute"
});

Вы также можете передать внешний ключ при создании, если хотите — просто обязательно используйте camelCase:

server.create('second-resource', {
  id: 36,
  firstResourceId: '11',
  myAttribute: "my_attribute"
});

Просто помните, что решения о форматировании таких вещей, как атрибуты и внешние ключи (например, some-attribute против some_attribute или relationship-id против relationship_id) принимаются на уровне сериализатора. При работе с ORM и базой данных Mirage вы должны придерживаться camelCase, независимо от формата, который выдает ваш сериализатор.


Для получения дополнительной информации ознакомьтесь с этими разделами документации:

person Sam Selikoff    schedule 10.03.2019
comment
Спасибо за эти советы, я кое-что запутался, потому что были дашеризированы: server.create('second-resource', { camelCased: firstResourceId: '11', underscored: 'second_resources': { Еще я заметил, что у меня некоторые плохо сконфигурированные вещи.После того, как я улучшил эти соединения, а также фиксированные ассоциации на сериализаторах, я также добавил: : 'всегда', нормализовать (полезная нагрузка) { (...) } - person Hubert Olender; 12.03.2019
comment
Теперь документация намного лучше, чем я начал с ней. Я признателен за это. После того, что я добавляю туда, я не вижу ссылок: { в моем ответе, не уверен, что это правильное поведение на мираже или мне нужно установить что-то еще. - person Hubert Olender; 12.03.2019
comment
Ознакомьтесь с разделом ссылок Сериализатор, или, если вы не используете JSONAPISerializer, вы можете добавить их после вызова super в методе сериализации (см. документацию по методу serialize). - person Sam Selikoff; 16.03.2019
comment
Спасибо за ответы и за то, что показали мне эти ссылки, которые прилипли к делу. После этих предложений я провел рефакторинг около 100 файлов. Одной из самых запутанных вещей было то, что у Mirage factory, например, my_type (с подчеркиванием) - этот атрибут работает с server.create('resource'). Когда я сделал server.create('resource', {my_type: 'something'}), это сработало. Когда я сделал server.create('resource', {myType: 'something')) это не сработало. Когда я сменил factory на myType, то server.create('resource', {myType: 'something')) заработало. У меня была смесь этого, и это вызвало головную боль. Спасибо. - person Hubert Olender; 21.03.2019