-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
JSON-API correct handling of included entities #3380
Comments
Looks like we had a regression where the @wwwdata do you mind trying http://builds.emberjs.com/canary/ember-data.js to see if the issue is fixed? |
the error is still there. I wrote a small test: wwwdata@36a62a2 the |
@bmac @wwwdata Is this caused by the following line? https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/relationships/state/has-many.js#L176 |
Also this PR might be related to this issue: #3122 |
@steffenbrem yes, that is the line, when i always use the |
I've looked into this (including #3122) and even though it might seems trivial at first (let local data take precedence over links) I fear it's not. We have the scenario when you have a link but no data and then fetch the data. So far so good. But if the link gets updated we want to invalidate the cache and refetch the next time we get the records. There's a test for this here. Having local data take precedence over links breaks this. Another scenario is when you have a link and then create a new local record. This means we do have data but we still haven't fetched the link. In this scenario we want to fetch the link and merge the results with the newly created record and return them together. There's currently a test for this here. Having local data take precedence over links breaks this too. With JSON-API I'm suspecting it will be more and more common having both links and data returned from backends and in many of those cases the data should take precedence over links. This is absolutely something we should solve, I just don't know how yet. Edit: With "having data" I'm referring to the internal |
@wecc My two cents on how to solve the issues you described above. For the first scenario, couldn't you just keep the dirty state of the link, so only take data presendence if the link is not "dirty". The link will be in a dirty state once it is different for the same relationship. For the second scenario, I think you could easily track this by checking if the specific relation you are requesting has embedded data loaded, so some property should be set on every relationship that says if is has the data or not. I don't know if this is realistic, since I am not an Ember Data expert. But I think it shouldn't be that hard to solve it. If needed, I could try to make a PR that implements my points. |
@steffenbrem 👍 go for it please and make a PR. I think we should just check if there are some reference IDs in the The link however always makes sense, because you might want to check at a later time if there are more referenced entities. For example if you loaded a blog post and just want to reload comments. Maybe ember-data at sometime needs another method to explicitly force loading of related entities via a related link for this special case. But as first step it would be awesome to just take stuff from the |
@steffenbrem @wwwdata The problem is, as I see it, that we want different outcomes from two different scenarios that we're currently unable to tell apart:
|
@wecc So basically, we need to be able to know if the relationship has its data from the server or it is only local data. Something like that? I think that covers the issue we are having. So lets say we introduce
I can't think of another way to solve this properly. I am going to sleep now, but when I have time I will check if it is possible to keep track of data loaded from the server, so we can have such a property as @igorT Do you have any ideas on this maybe? |
Just to summarise and to help newcomers getting into Ember Data and using the JSONAPIAdapter. There's a bug where The bug is apparent when the API response returns with data ids and there is already an The bug is also apparent in this scenario.
Instead of Ember Data executing a coalesce (batch) query like:
It follows the Apply this workaround without having to remove the I believe it is IMPORTANT that the workaround be applied to expect the desired behaviour from Ember Data, in any scenario. Credit to @wecc. In the application serializer (
|
@krzkrzkrz smart workaround. Thanks ;) |
is there an equivalent method i can override on active model serializer to do something similar? should i file an issue on https://github.com/ember-data/active-model-adapter also? |
@jcope2013 I think you should be able to do pretty much the same if you call |
@wecc that doesn't seem to work, relationshipHash comes in to the method as a string of the modelName which seems odd and what it returns when calling
|
yeah, that sound's really odd. can you create a separate issue with a JSBin demonstrating the issue? (preferably using your real payload) |
Would it make sense to also distinguish between data: [] and null, the former representing from the server that there are no related records vs the latter implying that the server doesn't know and should query? |
any news on the team decision? In order to really use ember-data with jsonapi 1.0 we need a good way to treat relationships and also make them optional if needed, so that they are requested only if needed from the specified relationship URL. |
Any update on the position of the team regarding this? |
bump |
Seeing the same issue with [email protected], not even using relationship links at all (One-to-One). //models/article.js
DS.Model.extend({
title: attr('string'),
comment: belongsTo('comment')
}); JSONAPI payload: {
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "Rails is Omakase"
},
"relationships": {
"comment": {
"data": { "type": "comment", "id": "1" }
}
}
},
"included": [
{
"type": "comments",
"id": "1",
"attributes": {
"author": "Dan",
"title": "Gebhardt",
}
}
]
} Route where the fetch occurs //app/routes/foo.js
Ember.Route.extend({
model() {
return this.store.findRecord('article', 1);
},
afterModel(article) {
return article.get('comment'); // makes a seperate request /host/namespace/comments/:id instead of using "included".
}
} |
@xomaczar I'm unable to reproduce this, see http://emberjs.jsbin.com/catohelode/edit?html,js,output Would you be able to create a JSBin demonstrating the issue? Feel free to open a new issue since this one is old and very long. |
@wecc here is the failing JSBin: http://emberjs.jsbin.com/cezowa/edit?html,js,console,output |
@wecc is this issue legit? |
@xomaczar not a bug, more unfortunate circumstances :) article:1 is already loaded when you enter the second route so the promise is resolved straight away using the article in store (without comments). Your template then tries to access comments and triggers a fetch. Meanwhile ED has background reloaded your article (see the new shouldBackgroundReloadRecord hook iirc) and the comments are side loaded and displayed correctly even though you get at "failed" comments fetch. So, the behavior you're seeing is by design, but not very easy to spot. Ping me in Slack of you want, should be an easy fix. |
This is precisely what I am currently seeing. Right now I override shouldReloadRecord on the first model adapter to always return true, stopping the promise from being resolved straight away. What is a better real solution here? |
The implementation currently always loads
related
entities from the provided url. If there are ids inside adata
object in a relation that match the ids of objects inside theincluded
object, those already loaded objects must be taken instead of requesting them from therelated
url, because that is not necessary.basic example
here, the author got already provided in the
included
object and does not need to be fetched.The text was updated successfully, but these errors were encountered: