Skip to content

Instantly share code, notes, and snippets.

@kjhangiani
Last active July 21, 2018 00:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kjhangiani/a33872a20ef7b7279c6a6566132564cb to your computer and use it in GitHub Desktop.
Save kjhangiani/a33872a20ef7b7279c6a6566132564cb to your computer and use it in GitHub Desktop.
ember polymorphic sideload
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: attr('string'),
commentableId: attr('number'),
commentable: 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": {
"active-model-adapter": "2.1.1",
"ember-data": "3.3.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment