Skip to content

findHasMany should be called instead of findMany if a has-many relationship is undefined #2162

@tomdale

Description

@tomdale

Given a payload for a particular record, Ember Data currently resolves has-many relationships through the adapter using the following heuristic:

  1. If the relationship is defined in the top-level links object, the store will call the adapter's findHasMany hook.
  2. If the relationship is not defined in the top-level links object, the store will call the adapter's findMany hook, passing it the array of IDs provided in the payload after removing the IDs of any records that are already loaded.

This behavior works well when the relationship is provided as a URL in the links object, or when the relationship is provided as an array of IDs.

However, there is a third, very common case, where the relationship should be populated by fetching a URL, but the URL is derived from information contained in the record, rather than being provided in the payload, hypermedia-style.

For example, imagine the following model:

// models/post.js
var attr = DS.attr,
    hasMany = DS.hasMany;
export default DS.Model.extend({
  title: attr(),
  body: attr(),
  comments: hasMany()
});

In this example, materializing the comments relationship by calling post.get('comments') should result in the client retrieving /post/123/comments. Thus, the server sends the following payload for the post with ID 123:

{
  "id": 123,
  "title": "Rails is Omakase",
  "body": "Trololol"
  // Note lack of comments relationship
}

This case is extraordinarily common (I ran into it when writing an app that uses the Portland public transit API, and Django's REST framework uses this approach), but currently getting this to work requires synthesizing a fake links entry in the serializer's normalizePayload hook and filling it with garbage data, which is a huge PITA.

@wycats and I think that it may be appropriate to add a third hook, which generates a URL for the relationship, and if that returns a value, the store will call findHasMany with the result. The current links behavior can be explained and implemented in terms of this new hook.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🏷️ featThis PR introduces a new feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions