Skip to content

Instantly share code, notes, and snippets.

@davelindquist-egistix
Last active August 11, 2020 13:04
Show Gist options
  • Save davelindquist-egistix/5fd0892440b64337440c13d4317ed295 to your computer and use it in GitHub Desktop.
Save davelindquist-egistix/5fd0892440b64337440c13d4317ed295 to your computer and use it in GitHub Desktop.
Ember Data Self-Referential Relationship Bug
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class extends Component {
@service store;
@tracked saved;
constructor() {
super(...arguments);
};
@action save() {
let record = this.store.createRecord('company');
record.save();
this.saved = true;
}
}
import Controller from '@ember/controller';
export default class ApplicationController extends Controller {
appName = 'Ember Data Self-Referential Relationship Bug';
constructor() {
super(...arguments);
$.mockjax({
type: 'post',
url: '/companies',
responseTime: 100,
responseText: {
data: {
type: "company",
id: 1,
attributes: {
"name": "Test Company"
},
relationships: {
parent: {
data: {
type: "company",
id: 1
}
}
}
}
}
});
}
}
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo } from 'ember-data/relationships';
export default class extends Model {
@attr("string") companyname
@belongsTo('company', {inverse: null} ) parent
}
<p>This test shows what happens if you save a record to the backend, and the backend fills in a relationship that happens to be self-referential.</p>
<p>Specifically, when Ember Data receives the backend response, it crashes, indicating that the given "id" is already in the store.</p>
<p>(This occurs because Ember Data first parses the relationships, adding a 'placeholder' to the store for the relationship, then proceeds to parse the object itself - unfortunately, by the time it gets to the id of the object, the relationship has already emplaced that id in the store, causing a failure.)</p>
Click the 'Save' button to simulate: <button onclick={{action 'save'}}>Save</button>
{{#if saved}}
<p>Now go and check the console -- you'll see an assertion failure from InternalModelFactory.setRecordId saying Uncaught Error: Assertion Failed: 'company' was saved to the server, but the response returned the new id '1', which has already been used with another record.'</p>
{{/if}}
{
"version": "0.17.1",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"ember": "3.12.2",
"ember-template-compiler": "3.12.2",
"ember-testing": "3.12.2",
"jquery-mockjax": "https://cdn.jsdelivr.net/npm/[email protected]/src/jquery.mockjax.min.js"
},
"addons": {
"@glimmer/component": "1.0.0",
"ember-data": "3.12.5"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment