Skip to content

Instantly share code, notes, and snippets.

@runspired
Forked from kjhangiani/adapters.application.js
Last active February 8, 2018 01:14
Show Gist options
  • Save runspired/1d395fcf2cfb39227599192cebe8ec5f to your computer and use it in GitHub Desktop.
Save runspired/1d395fcf2cfb39227599192cebe8ec5f to your computer and use it in GitHub Desktop.
ember polymorphic sideload
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
init() {
this._super();
this.posts = this.get('store').peekAll('post');
this.comments = this.get('store').peekAll('comment');
},
actions: {
clear() {
let store = this.get('store');
store.unloadAll('post');
store.unloadAll('comment');
this.set('model', null);
},
getPost(id) {
let store = this.get('store');
this.set('model', store.peekRecord('post', id));
},
loadPosts() {
let store = this.get('store');
store.push({
data: {
id: 1,
type: 'post',
attributes: { name: 'Post 1' }
}
});
},
loadComments() {
let store = this.get('store');
store.push({
data: [
{
type: 'comment',
id: '1',
attributes: {
commentableId: 1,
commentableType: 'Post'
},
relationships: {
commentable: {
data: { id: '1', type: 'post' }
}
}
},
{
type: 'comment',
id: '2',
attributes: {
commentableId: 1,
commentableType: 'Post'
},
relationships: {
commentable: {
data: { id: '1', type: 'post' }
}
}
}
]
});
}
}
});
import Ember from 'ember';
import DS from 'ember-data';
export default Ember.Mixin.create({
comments: DS.hasMany(
'comment',
{
async: true,
inverse: 'commentable'
}
),
});
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(),
commentableId: attr(),
commentable: belongsTo(
'commentable',
{
inverse: 'comments',
polymorphic: true,
async: true
}
),
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import Commentable from 'twiddle/mixins/commentable';
export default Model.extend(Commentable, {
name: attr()
});
<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>
<table style="width: 100%;">
<thead>
<tr>
<th>Posts</th>
<th>Comments</th>
<th>Post Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td>
{{#each posts as |post|}}
Post:{{post.id}}<br>
{{else}}
No posts yet.<br><button {{action "loadPosts"}}>Load Posts</button>
{{/each}}
</td>
<td>
{{#each comments as |comment|}}
Comment:{{comment.id}}<br>
{{else}}
No posts yet.<br><button {{action "loadComments"}}>Load Posts</button>
{{/each}}
</td>
<td>
{{#if model}}
{{else}}
Setup Model<br><button {{action "getPost" '1'}}>Set Model to Post 1</button>
{{/if}}
</td>
</tr>
</tbody>
</table>
<br><br>
<div>
<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}}
<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>
{
"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.17"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment