Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Known belongsTo ids cannot use a link in a RESTSerializer #4292

Closed
jevanlingen opened this issue Mar 31, 2016 · 10 comments · Fixed by #5410
Closed

Known belongsTo ids cannot use a link in a RESTSerializer #4292

jevanlingen opened this issue Mar 31, 2016 · 10 comments · Fixed by #5410

Comments

@jevanlingen
Copy link

In a 'normal' situation there are two possibilities to obtain a belongsTo relation when using the RESTSerializer:

  1. Add the relation id to the response of owner object; Ember will automatically fetch the model by /name-of-model-plural/{:id}.
  2. Add a links object in the normalize function of own created serializer to obtain the data. Ember will fetch the model by given link.

So far, so good. But something goes wrong if both the relation id is available in the response and links object is also setted in your own created serializer.

Ember does still call /name-of-model-plural/{:id}, instead of calling /own-given-link/{:id}.
See Ember Twiddle for a live example.

@pangratz
Copy link
Member

It looks like this is currently the actual expected behavior.

As a workaround you can use the ds-references feature (currently available in 2.5.0-beta-1) and reload the type relationship of the file (see this updated ember-twiddle).

@bmac
Copy link
Member

bmac commented Mar 31, 2016

@wecc Do you remember why we made it work this way?

@pangratz
Copy link
Member

Looks like this has been introduced in #3762. Also maybe related to last comment by @wecc here.

@wecc
Copy link
Contributor

wecc commented Mar 31, 2016

IIRC the original reason why local data has precedence over links is so that included resources will be utilized. I haven't looked into the details enough but I think we're unable to tell the difference between a resource identifier only and resource identifier where it's resource is available in the store.

As I'm typing this I kind of want to remember that this (WIP test) is related... we need to be smarter with the hasData flag when we setup the relationships and I was bugging @igorT about it a while back.

@pangratz
Copy link
Member

@jevanlingen another workaround is to update the normalize of your file serializer to only specify the link for the type relationship, and delete the type (aka the id for the type relationship):

// app/serializers/file.js
export default DS.RESTSerializer.extend({
  normalize(typeClass, hash) {
    if (hash.type) {
      hash.links = {
        type: `/returns-file-type-from-other-api/${hash.type}`
      }

      // delete hash.type so the type relationship is only specified via
      // the link (which is added above)
      delete hash.type;
    }

    return this._super(...arguments);
  }
});

@bmac
Copy link
Member

bmac commented Mar 31, 2016

@wecc based on what you are saying it sounds like it should be possible for Ember Data data to use findBelongsTo in the case where there is an id but no record for that id is loaded into the store.

@wecc
Copy link
Contributor

wecc commented Mar 31, 2016

@bmac yeah, it should be possible. I'm trying to find the code I did to make that test I linked pass, I suspect it should solve this issue too, but no luck :(

@jevanlingen
Copy link
Author

Thanks for all the comments, for now I will use latest workaround @pangratz mentioned. I am still looking forward to a final solution from Ember Data Team :).

@wecc
Copy link
Contributor

wecc commented Oct 21, 2016

I've been looking into this during our week here in 🇬🇷 and below is pretty much my suggestion to how this should work. It would probably introduce som backwards-incompatible changes so there's that to consider as well.

Facts

  1. A relationship may or may not contain data with Resource Identifier(s)
  2. A relationship may or may not contain a related link
  3. Resource Identifier(s) contained in a relationship's data might or might not point to a Resource Object present in the store

belongsTo

Proposed priority:

  • If we have an identifier in the relationship's data then we want to prioritize what’s already in the store, then the related link, then findRecord(id).
  • If we don’t have data, prioritize the related link or return null.

Pseudo code:

if (relationship.resourceIdentifier) {
  if (store.hasResource(relationship.resourceIdentifier)) {
    return store.peekRecord(relationship.resourceIdentifier)
  }
  if (relationship.relatedLink) {
    return adapter.findBelongsTo(relationship.relatedLink)
  }
  return adapter.findRecord(relationship.resourceIdentifier)
} else {
  if (relationship.relatedLink) {
    return adapter.findBelongsTo(relationship.relatedLink)
  }
  return null
}

hasMany

Proposed priority:

  • If we have identifiers in data then we want to prioritize what’s already in the store, then the related link, then findRecord(id).
  • If we don’t have data, prioritize the related link or return empty ManyArray.

Pseudo code:

if (relationship.resourceIdentifiers) {
  resourcesInStore = store.peekRecords(relationship.resourceIdentifiers)
  if (diff(resourcesInStore, relationship.resourceIdentifiers).length == 0) {
    return resourcesInStore
  }
  if (relationship.relatedLink) {
    return adapter.findHasMany(relationship.relatedLink)
  }
  return adapter.findRecord(diff(resourcesInStore, relationship.resourceIdentifiers))
} else {
  if (relationship.relatedLink) {
    return adapter.findBelongsTo(relationship.relatedLink)
  }
  return null
}

self links

We would need to create a strategy forself links when we've got support for that. Basically I would suggest thatself links for relationships and records should only be used for reloading the current state of the object in question - nothing else. But that's out of scope for the proposal above.

@BryanCrotaz
Copy link
Contributor

What's the status of this? I think I've hit it in #5037

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants