Ember: Связанные данные привязки ссылок не загружаются/исчезают

Я испытываю некоторую ошибку с данными Ember/Ember. Здесь мой сценарий:

  • Клиент приземляется на трассе /, а Ember загружает данные из /api/v1/videos?limit=8. Ответ исходит из бэкэнда rails-api, используя active_model_serializers, который гарантирует, что ответ соответствует JSON API. Теперь в хранилище загружено 8 произвольных видеороликов.

  • Каждый видеокомпонент в DOM имеет ссылку на страницу пользователя (видео belongsTo пользователя и видео пользователя hasMany).

  • Клиент нажимает на link-to, который переходит на /users/1, который представляет пользователя с идентификатором 1

  • Крючок модели для этого маршрута загружает только одну запись пользователя. Запись пользователя имеет следующую полезную нагрузку:

{
    "data": {
        "id": "1",
        "relationships": {
            "videos": {
                "data": [],
                "links": {
                    "related": "/api/v1/videos?user_id=1"
                }
            },
        },
        "type": "users"
    }
}

Проблема заключается в том, что ember автоматически не отправляет запрос для /api/v1/videos?user_id=1 (предположительно потому, что уже был выполнен аналогичный запрос /api/v1/videos?limit=8).

Если я непосредственно загружаю страницу /users/1, тогда Ember умнее и автоматически загружает данные из конечной точки /api/v1/videos?user_id=1.

Я подозреваю, что Ember обманывает тот факт, что аналогичный запрос к конечной точке видео уже произошел с разными параметрами запроса. Конечным результатом является то, что мое приложение не показывает никаких данных на странице пользователя.

Один из способов исправить это - не использовать ссылки/родственный синтаксис, но заполнить "data": [], идентификаторами видео, которые заставят ember отправлять n запросов для n видео. Это работает, но неприемлемо для приложения большого масштаба, где на странице пользователя могут быть сотни видеороликов.

Как я могу это исправить?

Вы можете видеть, что установка active_model_serializers для ссылок/связанной структуры должна быть специально для данных ember-данных.


Изменить: я попытался избавиться от data: [], используя include_data false в active_model_serializers, который не помог.


Изменить 2: Здесь полезная нагрузка /api/v1/videos?limit=8:

{
    "data": [
        ...
        {
            "attributes": {
                ...
            },
            "id": "325",
            "relationships": {
                "user": {
                    "data": {
                        "id": "1",
                        "type": "users"
                    }
                }
            },
            "type": "videos"
        },
        ...
    ]
}

Другими словами, некоторые из видео в этой полезной нагрузке могут принадлежать пользователю, которого мы позже загрузим.


Изменить 3: Я делаю это как обходной путь в маршруте пользователя:

afterModel(user) {
  user.hasMany('videos').reload();
})

Это немного глупо, но на данный момент это делается.


Изменить 4: Я пробовал обновление до ember и ember-data v3. Поведение сохраняется.

Ответ 1

Я создал Ember Twiddle с вашим прецедентом. Проверьте это, чтобы найти различия в вашей реализации. Мне очень интересно, почему это не сработает для вас. Я уверен, что это небольшая деталь, которую вам не хватает.


UPDATE

Получается (см. комментарии ниже), что emberjs/data не обрабатывает links.related-field, если предоставляется поле данных (resource-linkage)

relationships: {
  videos: {
    data: [], // if data is provided(resource linkage), ember won't fetch relationships via links.related
    links: {
      related: "/videos?user_id=4"
    }
  }
}

Я не могу найти это ограничение в JSON API DOC, поэтому я думаю, что это специфично для ember, но это не должно быть проблема, потому что данные: [] не имеют смысла, если ссылка-объект предоставлена, поэтому он должен быть опущен сериализатором.


Ответ 2

Я также вижу это - он работал с ember-data 2, но теперь не работает с ember-data 3.6

{
    "included": [],
    "data": {
        "id": "33z3unbqPsoONg",
        "type": "feed-asset",
        "links": {
            "schedules": "relationships/schedules",
            "createdBy": "relationships/created-by",
            "lastModifiedBy": "relationships/last-modified-by",
            "feed": "relationships/feed",
            "metadataValues": "relationships/metadata-values"
        },
        "relationships": {
            "created-by": {
                "links": {
                    "related": "relationships/created-by"
                }
            },
            "feed": {
                "links": {
                    "related": "relationships/feed"
                }
            },
            "fields": {
                "links": {
                    "related": "relationships/fields"
                }
            },
            "in-playlists": {
                "links": {
                    "related": "relationships/in-playlists"
                }
            },
            "last-modified-by": {
                "links": {
                    "related": "relationships/last-modified-by"
                }
            },
            "metadata-fields": {
                "links": {
                    "related": "relationships/metadata-fields"
                }
            },
            "owned-by": {
                "links": {
                    "related": "relationships/owned-by"
                }
            },
            "schedules": {
                "links": {
                    "related": "relationships/schedules"
                }
            },
            "metadata-values": {
                "links": {
                    "related": "relationships/metadata-values"
                }
            }
        },
        "attributes": {
            "item-duration": 2,
            "last-modified": "2019-01-24T14:12:42.672Z",
            "created": "2019-01-24T14:12:32.142Z",
            "draft": false,
            "number-of-items": 2,
            "name": "news",
            "is-available-to-collections": false
        }
    }
}