Skip to content

Commit

Permalink
fix: implicit inverse key gen needs to utilize the related type for u…
Browse files Browse the repository at this point in the history
…niqueness
  • Loading branch information
runspired committed Apr 30, 2021
1 parent fc731d3 commit 07c659c
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
6 changes: 3 additions & 3 deletions packages/record-data/addon/-private/graph/-edge-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ const BOOL_LATER = (null as unknown) as boolean;
const STR_LATER = '';
const IMPLICIT_KEY_RAND = Date.now();

function implicitKeyFor(key: string): string {
return `implicit-${key}${IMPLICIT_KEY_RAND}`;
function implicitKeyFor(type: string, key: string): string {
return `implicit-${type}:${key}${IMPLICIT_KEY_RAND}`;
}

function syncMeta(definition: UpgradedMeta, inverseDefinition: UpgradedMeta) {
Expand Down Expand Up @@ -191,7 +191,7 @@ export function upgradeDefinition(
// CASE: We have no inverse
if (!inverseDefinition) {
// polish off meta
inverseKey = implicitKeyFor(propertyName);
inverseKey = implicitKeyFor(type, propertyName);
inverseDefinition = {
kind: 'implicit',
key: inverseKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { module, test } from 'qunit';

import { setupTest } from 'ember-qunit';

import Model, { attr, belongsTo } from '@ember-data/model';
import { graphFor } from '@ember-data/record-data/-private';
import Store, { recordIdentifierFor } from '@ember-data/store';

module('Integration | Graph | Implicit Keys', function (hooks) {
setupTest(hooks);

hooks.beforeEach(function () {
const { owner } = this;
owner.register('service:store', Store);
});

test('Non-polymorphic records do not trigger polymorphic assertions when they share the same key with another record', async function (assert) {
const { owner } = this;
class User extends Model {
@attr name;
@belongsTo('organization', { async: false, inverse: null }) organization;
}
class Product extends Model {
@attr name;
@belongsTo('organization', { async: false, inverse: null }) organization;
}
class Organization extends Model {
@attr name;
}
owner.register('model:user', User);
owner.register('model:product', Product);
owner.register('model:organization', Organization);

const store = owner.lookup('service:store');
const graph = graphFor(store);
let user, product, organization;

assert.expectNoAssertion(() => {
[user, product, organization] = store.push({
data: [
{
type: 'user',
id: '1',
attributes: { name: 'Chris' },
relationships: {
organization: { data: { type: 'organization', id: '1 ' } },
},
},
{
type: 'product',
id: '1',
attributes: { name: 'Awesome Relationships' },
relationships: {
organization: { data: { type: 'organization', id: '1 ' } },
},
},
{
type: 'organization',
id: '1',
attributes: { name: 'Ember.js' },
},
],
});
});

const userIdentifier = recordIdentifierFor(user);
const productIdentifier = recordIdentifierFor(product);
const organizationIdentifier = recordIdentifierFor(organization);

const userOrg = graph.get(userIdentifier, 'organization');
const userImpl = graph.get(organizationIdentifier, userOrg.definition.inverseKey);
const productOrg = graph.get(productIdentifier, 'organization');
const productImpl = graph.get(organizationIdentifier, productOrg.definition.inverseKey);

assert.notStrictEqual(userImpl, productImpl, 'We have separate implicit caches');
});
});

0 comments on commit 07c659c

Please sign in to comment.