Skip to content

Commit

Permalink
Implement filterBy on DS.ManyArray
Browse files Browse the repository at this point in the history
  • Loading branch information
bmac committed Aug 3, 2015
1 parent 500ec3d commit 9109e0e
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 15 deletions.
33 changes: 33 additions & 0 deletions packages/ember-data/lib/system/many-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@module ember-data
*/
import { PromiseArray } from "ember-data/system/promise-proxies";
import FilteredSubset from "ember-data/system/record-arrays/filtered-subset";

var get = Ember.get;
var set = Ember.set;
Expand Down Expand Up @@ -277,5 +278,37 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
this.pushObject(record);

return record;
},

/**
Get a filtered subset of the underlying `ManyArray`.
The subset updates when a record would match or mismatch the
specified filter parameters.
Example
```javascript
var post = store.peekRecord('post', 1)
// All the comments that are deleted locally but not yet saved to the server.
var deletedComments = post.get('comments').filterBy('isDeleted');
```
@method filterBy
@param {String} key property path
@param {*} value optional
*/
filterBy: function(key, value) {
// only pass value to the arguments if it is present; this mimics the same
// behavior for `filterBy`: http://git.io/vIurH
var filterByArgs = [key];
if (arguments.length === 2) {
filterByArgs.push(value);
}

return FilteredSubset.create({
filterByArgs,
recordArray: this
});
}
});
15 changes: 15 additions & 0 deletions packages/ember-data/lib/system/record-arrays/filtered-subset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var FilteredSubset = Ember.ArrayProxy.extend({
init: function() {
this._super(...arguments);

var { filterByArgs, recordArray } = this.getProperties('filterByArgs', 'recordArray');
var [key] = filterByArgs;

var path = `recordArray.@each.${key}`;
Ember.defineProperty(this, 'content', Ember.computed(path, function() {
return this.filterBy.apply(recordArray, filterByArgs);
}));
}
});

export default FilteredSubset;
16 changes: 1 addition & 15 deletions packages/ember-data/lib/system/record-arrays/record-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,11 @@

import { PromiseArray } from "ember-data/system/promise-proxies";
import SnapshotRecordArray from "ember-data/system/snapshot-record-array";
import FilteredSubset from "ember-data/system/record-arrays/filtered-subset";

var get = Ember.get;
var set = Ember.set;

var FilteredSubset = Ember.ArrayProxy.extend({
init: function() {
this._super(...arguments);

var { filterByArgs, recordArray } = this.getProperties('filterByArgs', 'recordArray');
var [key] = filterByArgs;

var path = `recordArray.@each.${key}`;
Ember.defineProperty(this, 'content', Ember.computed(path, function() {
return this.filterBy.apply(recordArray, filterByArgs);
}));
}
});


/**
A record array is an array that contains records of a certain type. The record
array materializes records as needed when they are retrieved for the first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2340,3 +2340,75 @@ test("metadata should be reset between requests", function() {
});
});
});


test("filterBy - returns a filtered subset", function () {
var chapter, page;
run(function() {
env.store.push({
data: {
type: 'chapter',
id: '1',
relationships: {
pages: {
data: [
{ type: 'page', id: '2' },
{ type: 'page', id: '3' }
]
}
}
},
included: [{
type: 'page',
id: '2'
}, {
type: 'page',
id: '3'
}]
});
chapter = env.store.peekRecord('chapter', 1);
page = env.store.peekRecord('page', 2);
});
run(function() {
page.deleteRecord();
});
run(function() {
equal(chapter.get('pages').filterBy('isDeleted').get('length'), 1, "Can filter by deleted records");
});
});


test("filterBy - returns a filtered subset", function () {
var chapter;
run(function() {
env.store.push({
data: {
type: 'chapter',
id: '1',
relationships: {
pages: {
data: [
{ type: 'page', id: '2' },
{ type: 'page', id: '3' }
]
}
}
},
included: [{
type: 'page',
id: '2'
}, {
type: 'page',
id: '3'
}]
});
chapter = env.store.peekRecord('chapter', 1);
});
run(function() {
env.store.peekRecord('page', 2).deleteRecord();
var deletedChapters = chapter.get('pages').filterBy('isDeleted');
equal(deletedChapters.get('length'), 1);
env.store.peekRecord('page', 3).deleteRecord();
equal(deletedChapters.get('length'), 2);
});
});

0 comments on commit 9109e0e

Please sign in to comment.