Skip to content

Instantly share code, notes, and snippets.

@kjhangiani
Created February 8, 2018 00:25
Show Gist options
  • Save kjhangiani/d7f7a847cb0a3e93c4d0c5a8189c1967 to your computer and use it in GitHub Desktop.
Save kjhangiani/d7f7a847cb0a3e93c4d0c5a8189c1967 to your computer and use it in GitHub Desktop.
polymorphic relationship - ember-data 2.13.2
import Ember from 'ember';
import ActiveModelAdapter from 'active-model-adapter';
export default ActiveModelAdapter.extend({
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
posts: Ember.A(),
comments: Ember.A(),
actions: {
clear() {
this.store.unloadAll('post');
this.store.unloadAll('comment');
this.set('model', null);
},
getPost(id) {
this.set('model', this.store.peekRecord('post', id));
},
loadPosts() {
this.store.pushPayload({
posts: [
{ id: 1, name: 'Post 1' }
]
});
this.set('posts', this.store.peekAll('post'));
console.log('pushed post into store');
},
loadComments() {
this.store.pushPayload({
comments: [
{ id: 1, commentable_id: 1, commentable_type: 'Post' },
{ id: 2, commentable_id: 1, commentable_type: 'Post' },
]
});
this.set('comments', this.store.peekAll('comment'));
console.log('pushed comments into store');
},
}
});
import Ember from 'ember';
import DS from 'ember-data';
export default Ember.Mixin.create({
comments: DS.hasMany('comment', { async: false }),
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
commentableType: DS.attr('string'),
commentableId: DS.attr('number'),
commentable: DS.belongsTo('commentable', { polymorphic: true, async: true }),
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
import Commentable from 'twiddle/mixins/commentable';
export default Model.extend(Commentable, {
name: attr('string')
});
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{outlet}}
<br>
<br>
<h1>Instructions</h1>
<ol>
<li>Click "Load Posts" to push a post into the store via pushPayload</li>
<li>Click "Load Comments" to push comments into the store (with commentable_id, commentable_type for the above post)</li>
<li>Click "Render Post" to then render this post - note that the length of comments is 0 (even though posts and comments are in the store)</li>
<li>Click "Load Comments" a second time - note that this time, the length of comments will update</li>
</ol>
<br/><br/>
<div>
This appears to be due to the relationship not materializing unless .get('comments') is called first (via the template in this case) before the records are pushed into the store. However, the expectation is that after the records are in the store, .get('comments') should already have the relationship data.
<br/><br/>
This causes bugs when trying to sideload polymorphic models (whereby the primary model and polymorphic children are pushed into the store at the same time).
</div>
<br/><br/>
<div>
<button {{action "loadPosts"}}>Load Posts</button>
<button {{action "loadComments"}}>Load Comments</button>
<button {{action "getPost" 1}}>Render Post 1</button>
<button {{action "clear"}}>Clear Store</button>
</div>
<br/><br/>
<div>
The store contains {{posts.length}} posts and {{comments.length}} comments.
</div>
<br/><br/>
<div>
{{#if model}}
Post {{model.id}} is rendered and has {{model.comments.length}} comments.
{{/if}}
</div>
{
"version": "0.13.0",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.16.2",
"ember-template-compiler": "2.16.2",
"ember-testing": "2.16.2"
},
"addons": {
"ember-data": "2.13.2",
"active-model-adapter": "2.1.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment