Reputation: 1271
model:
DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
comments: DS.hasMany('comment', { async: true} ),
hasComments: Ember.computed.gt('comments.length', 0)
});
payload:
{
"id": "abcdefg",
"title": "some cats are cool",
"body": "",
"comments: ["100", "101", "102"]
}
But the hasComments
computed property triggers a fetch for each comment individually.. I don't want this :D
I know this works (avoids the fetch), but reaches into private API:
hasComments: Ember.computed.gt('data.comments.length', 0)
ember.js 1.8.1
ember-data 1.0.0-beta.11
Any other recommendations on achieving a computed property based off of the length
Upvotes: 5
Views: 1267
Reputation: 8251
As of Ember Data 2.5 (mentioned in release notes) there is a feature called ds-references
which provides a way to check if if a hasMany relationship contains items or not without triggering a fetch for those items:
export default Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
comments: DS.hasMany('comment', { async: true} ),
hasComments: Ember.computed('comments', function() {
return this.hasMany('comments').ids().length > 0;
})
});
See this working in an Ember Twiddle
The ds-references feature implements the references API as described in RFC 57. References is a low level API to perform meta-operations on records, has-many relationships and belongs-to relationships:
- get the current local data synchronously without triggering a fetch or producing a promise
- notify the store that a fetch for a given record has begun, and provide a promise for its result
- similarly, notify a record that a fetch for a given relationship has begun, and provide a promise for its result
- retrieve server-provided metadata about a record or relationship
Source: Ember forum post and Ember Data 2.5 release blog post
Upvotes: 6
Reputation: 9624
I wish there was an easy way to do this. The simplest way I can think of is to override extractHasMany
in your serializer and save a new property, commentsCount
, on your model, eg:
models/post.rb:
DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
comments: DS.hasMany('comment', { async: true} ),
commentsCount: DS.attr('number'),
hasComments: Ember.computed.gt('commentsCount', 0)
});
serializers/post.rb:
export default ApplicationSerializer.extend({
normalizeHash: {
posts(hash) {
hash.comments_count = hash.comments.length;
return hash;
}
}
}
Be careful though, as the commentsCount property will not automatically recompute in this case when you add/remove comments. You could probably build a computed property that uses the actually comments instead of commentsCount
if the comments are loaded.
Upvotes: 0
Reputation: 713
You mentioned, that each comment was fetched individually. This can be avoided by setting coalesceFindRequests on the RestAdapter, if your backend supports this.
Yet, you'd still have one request too many. I don't think, that that can be avoided without some kind of dirty trick, but am open to learn from other answers.
Upvotes: 0