Skip to content

Commit

Permalink
Merge pull request #2576 from emberjs/relationship_changes
Browse files Browse the repository at this point in the history
Relationship changes
  • Loading branch information
igorT committed Dec 18, 2014
2 parents 9e6d95e + b1fdb4b commit 2511ac8
Show file tree
Hide file tree
Showing 17 changed files with 850 additions and 505 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ docs/node_modules/

node_modules/
bower_components/
.metadata_never_index
2 changes: 1 addition & 1 deletion packages/ember-data/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import "ember-data/ember-initializer";
import setupContainer from "ember-data/setup-container";

import ContainerProxy from "ember-data/system/container_proxy";
import {Relationship} from "ember-data/system/relationships/relationship";
import Relationship from "ember-data/system/relationships/state/relationship";

DS.Store = Store;
DS.PromiseArray = PromiseArray;
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-data/lib/system/model/model.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import RootState from "ember-data/system/model/states";
import Errors from "ember-data/system/model/errors";
import { PromiseObject } from "ember-data/system/promise_proxies";
import { createRelationshipFor } from "ember-data/system/relationships/relationship";
import merge from "ember-data/system/merge";
import JSONSerializer from "ember-data/serializers/json_serializer";
import createRelationshipFor from "ember-data/system/relationships/state/create";

/**
@module ember-data
Expand Down
28 changes: 1 addition & 27 deletions packages/ember-data/lib/system/record_array_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import {
RecordArray,
FilteredRecordArray,
AdapterPopulatedRecordArray,
ManyArray
AdapterPopulatedRecordArray
} from "ember-data/system/record_arrays";
import {
MapWithDefault,
Expand Down Expand Up @@ -158,31 +157,6 @@ export default Ember.Object.extend({
}
},

/**
Create a `DS.ManyArray` for a type and list of record references, and index
the `ManyArray` under each reference. This allows us to efficiently remove
records from `ManyArray`s when they are deleted.
@method createManyArray
@param {Class} type
@param {Array} references
@return {DS.ManyArray}
*/
createManyArray: function(type, records) {
var manyArray = ManyArray.create({
type: type,
content: records,
store: this.store
});

forEach(records, function(record) {
var arrays = this.recordArraysForRecord(record);
arrays.add(manyArray);
}, this);

return manyArray;
},

/**
Create a `DS.RecordArray` for a type and register it for updates.
Expand Down
92 changes: 78 additions & 14 deletions packages/ember-data/lib/system/record_arrays/many_array.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import RecordArray from "ember-data/system/record_arrays/record_array";

/**
@module ember-data
*/
Expand Down Expand Up @@ -42,11 +40,46 @@ var get = Ember.get, set = Ember.set;
@namespace DS
@extends DS.RecordArray
*/
export default RecordArray.extend({
export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
init: function() {
this._super.apply(this, arguments);
this.currentState = Ember.A([]);
this.diff = [];
},

record: null,

canonicalState: null,
currentState: null,

diff: null,

length: 0,

objectAt: function(index) {
if (this.currentState[index]) {
return this.currentState[index];
} else {
return this.canonicalState[index];
}
},

flushCanonical: function() {
//TODO make this smarter, currently its plenty stupid
var toSet = this.canonicalState.slice(0);
//a hack for not removing new records
//TODO remove once we have proper diffing
var newRecords = this.currentState.filter(function(record) {
return record.get('isNew');
});
toSet = toSet.concat(newRecords);
this.arrayContentWillChange(0, this.length, this.length);
this.set('length', toSet.length);
this.currentState = toSet;
this.arrayContentDidChange(0, this.length, this.length);
//TODO Figure out to notify only on additions and maybe only if unloaded
this.relationship.notifyHasManyChanged();
this.record.updateRecordArrays();
},
/**
`true` if the relationship is polymorphic, `false` otherwise.
Expand All @@ -70,7 +103,48 @@ export default RecordArray.extend({
*/
relationship: null,

internalReplace: function(idx, amt, objects) {
if (!objects) {
objects = [];
}
this.arrayContentWillChange(idx, 0, objects.length);
this.currentState.splice.apply(this.currentState, [idx, amt].concat(objects));
this.set('length', this.currentState.length);
this.arrayContentDidChange(idx, 0, objects.length);
if (objects){
//TODO(Igor) probably needed only for unloaded records
this.relationship.notifyHasManyChanged();
}
this.record.updateRecordArrays();
},

//TODO(Igor) optimize
internalRemoveRecords: function(records) {
var index;
for(var i=0; i < records.length; i++) {
index = this.currentState.indexOf(records[i]);
this.internalReplace(index, 1);
}
},

//TODO(Igor) optimize
internalAddRecords: function(records, idx) {
if (idx === undefined) {
idx = this.currentState.length;
}
this.internalReplace(idx, 0, records);
},

replace: function(idx, amt, objects) {
var records;
if (amt > 0){
records = this.currentState.slice(idx, idx+amt);
this.get('relationship').removeRecords(records);
}
if (objects){
this.get('relationship').addRecords(objects, idx);
}
},
/**
Used for async `hasMany` arrays
to keep track of when they will resolve.
Expand Down Expand Up @@ -101,16 +175,6 @@ export default RecordArray.extend({
}
},

replaceContent: function(idx, amt, objects){
var records;
if (amt > 0){
records = get(this, 'content').slice(idx, idx+amt);
this.get('relationship').removeRecords(records);
}
if (objects){
this.get('relationship').addRecords(objects, idx);
}
},
/**
@method reload
@public
Expand Down
6 changes: 1 addition & 5 deletions packages/ember-data/lib/system/relationships/belongs_to.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,7 @@ function belongsTo(type, options) {
@namespace DS
*/
Model.reopen({
notifyBelongsToAdded: function(key, relationship) {
this.notifyPropertyChange(key);
},

notifyBelongsToRemoved: function(key) {
notifyBelongsToChanged: function(key) {
this.notifyPropertyChange(key);
}
});
Expand Down
13 changes: 3 additions & 10 deletions packages/ember-data/lib/system/relationships/has_many.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,21 +122,14 @@ function hasMany(type, options) {
}

Model.reopen({
notifyHasManyAdded: function(key, record, idx) {
var relationship = this._relationships[key];
var manyArray = relationship.manyArray;
manyArray.addRecord(record, idx);
notifyHasManyAdded: function(key) {
//We need to notifyPropertyChange in the adding case because we need to make sure
//we fetch the newly added record in case it is unloaded
//TODO(Igor): Consider whether we could do this only if the record state is unloaded

//Goes away once hasMany is double promisified
this.notifyPropertyChange(key);
},

notifyHasManyRemoved: function(key, record) {
var relationship = this._relationships[key];
var manyArray = relationship.manyArray;
manyArray.removeRecord(record);
}
});


Expand Down
Loading

0 comments on commit 2511ac8

Please sign in to comment.