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

[FEAT BUGFIX] resolves issues with links and data in relationships #5410

Merged
merged 13 commits into from Apr 6, 2018

Conversation

runspired
Copy link
Contributor

@runspired runspired commented Apr 3, 2018

Description

This PR includes two fixes for links and a suite of new tests to accompany them.

The first addresses a shortcoming of the lazy-relationships work which caused meta and links information to be lossy. We now "merge forward" meta and links information on relationship payloads when necessary. We also now handle data for has-many relationships discovered via their inverse in a special way (see _partialData). This avoids us losing information about whether the membership should be considered complete or not.

The second addresses the situation in which both data and links are present for a relationship. We now ALWAYS prefer to fetch/re-fetch relationship data via a link if present. To achieve this, we now do a minimal amount of book-keeping on whether the relationship should be considered available locally, or must be refetched.

General Warning

This PR cleans up some previously poorly spec'd behavior, which means that it may cause some minor breakage to apps using links that had found work-arounds for the mixing links and data issue.

Because it fixes our ability to use links for relationships in general, folks that implemented workarounds for relationships expecting their links to never be used might be particularly surprised. Ideally things will "just work"™ in most situations for these folks, and they can delete their workarounds.

Resolves and/or supplants

It additionally advances the status of #2905 and #2162

@runspired runspired requested review from hjdivad and wecc April 3, 2018 17:31
localStateIsEmpty() {
let manyArray = this.manyArray;
let internalModels = manyArray.currentState;
let manyIsArrayLoaded = manyArray.get('isLoaded');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/manyIsArrayLoaded/manyArrayIsLoaded perhaps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

confirm, was dyslexic.

@@ -77,6 +77,7 @@ export default class Relationship {
this.meta = null;
this.hasData = false;
this.hasLoaded = false;
this.hasLocalData = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the case where hasData && !hasLocalData?

ie how does "local" data differ from data?

Does this capture explicit data in a json-api resource as opposed to data loaded from a link in a json-api resource that initially contained no data?

Copy link
Contributor Author

@runspired runspired Apr 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasData really means hasRelationshipDataProperty, it doesn't indicate whether that data has been loaded or not. It's quite possible to have relationshipData and have incomplete data locally.

Example:

{
 data: {
   type: 'foo',
   id: '1',
   relationships: {
     bars: {
        data: [ { type: 'bar', id: '1' } ],
        links: { related: './bars' }
     }
   }
 }
}

In the above case even though we know which bars the links ought to provide, they have not been given to us in included and so unless they were already available locally we would need to fetch. To cover this, I now do a dirty check for isEmpty to see if we have data.

It might be more clear to update the existing hasData prop to be hasRelationshipDataProperty

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe (probably) because I'm french, but I would (wrongly?) better understand relationshipHasDataProperty.

Copy link
Member

@bmac bmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@wecc wecc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (💯 on the new name), great work @runspired

@runspired
Copy link
Contributor Author

I added 25 new tests to ensure full coverage of the links+data issue. We have 8 failures but I think they should be pretty easy to resolve.

let hasData = get(this.hasManyRelationship, 'hasData');
if (!hasData) {
let hasRelationshipDataProperty = get(this.hasManyRelationship, 'hasAnyRelationshipData');
if (!hasRelationshipDataProperty) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be noted for a follow up PR to be changed. No tests failed but now that we've clarified what the flags are it is rather obvious that this is not correct.

'\nUse `record.belongsTo(relationshipName).meta()` instead.',
false
);
}),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sidenote: this is actually true for hasMany as well. It does proxy meta, however it rarely picks up the change notification (if ever). We should address this soon.

@bmac
Copy link
Member

bmac commented Apr 6, 2018

Thanks @runspired.

@BryanCrotaz
Copy link
Contributor

Wow. Nicely done.

@sandstrom
Copy link
Contributor

Awesome @runspired 🥇 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment