ember-data-source 1.0.0.beta.10 → 1.0.0.beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f48e9de804e7633cde2ee245cb9c063c804d72b1
4
- data.tar.gz: c15a96192b9ebd3fc000f41cb44596d6e781eb26
3
+ metadata.gz: 22471a9db952110eb0fb9232b5789dd5691dceff
4
+ data.tar.gz: a203dd086407b2cb9d24856f1e0749c9bad84dbb
5
5
  SHA512:
6
- metadata.gz: 1c362c04dfee3d2950f41d76ade8f8d9ec631d19a7f7b5eba29333d7637b2f50c7385518a1a333eb6afe9c5fd2d272fe398db04a1054a1b737c5134258643759
7
- data.tar.gz: 0751401cf62b2d2e9d0ebc4e106aa8dbe858150facbfb28e1a8721bad1af95c3a9ffea2a554e10f7d88bedc635de9265db5587ae16a8c907e9addcf80c50940b
6
+ metadata.gz: 1ee867289a32ed33fd930dc6a830265d7abcebf171430b76bacbb30e6ec759fdc18056fa11af82d319c4273fbf0cb7334ea7d22d59d305f9390fb773433aa658
7
+ data.tar.gz: aa3fed45c6665b7435ae008ddf7c9e6db455d6e64f7334dfb4f46f31ce41bfc74831c4129e03c8b058e42ea4154abd355f0e582ca42229e54414c4ac4227601d
@@ -2,10 +2,26 @@
2
2
  var define, requireModule, require, requirejs;
3
3
 
4
4
  (function() {
5
+
6
+ var _isArray;
7
+ if (!Array.isArray) {
8
+ _isArray = function (x) {
9
+ return Object.prototype.toString.call(x) === "[object Array]";
10
+ };
11
+ } else {
12
+ _isArray = Array.isArray;
13
+ }
14
+
5
15
  var registry = {}, seen = {}, state = {};
6
16
  var FAILED = false;
7
17
 
8
18
  define = function(name, deps, callback) {
19
+
20
+ if (!_isArray(deps)) {
21
+ callback = deps;
22
+ deps = [];
23
+ }
24
+
9
25
  registry[name] = {
10
26
  deps: deps,
11
27
  callback: callback
@@ -274,7 +290,7 @@ define("activemodel-adapter/system/active_model_adapter",
274
290
  https://tools.ietf.org/html/rfc4918#section-11.2
275
291
 
276
292
  @method ajaxError
277
- @param jqXHR
293
+ @param {Object} jqXHR
278
294
  @return error
279
295
  */
280
296
  ajaxError: function(jqXHR) {
@@ -463,7 +479,7 @@ define("activemodel-adapter/system/active_model_serializer",
463
479
  @method serializePolymorphicType
464
480
  @param {DS.Model} record
465
481
  @param {Object} json
466
- @param relationship
482
+ @param {Object} relationship
467
483
  */
468
484
  serializePolymorphicType: function(record, json, relationship) {
469
485
  var key = relationship.key;
@@ -1059,8 +1075,8 @@ define("ember-data/adapters/fixture_adapter",
1059
1075
  });
1060
1076
  });
1061
1077
  define("ember-data/adapters/rest_adapter",
1062
- ["ember-data/system/adapter","exports"],
1063
- function(__dependency1__, __exports__) {
1078
+ ["ember-data/system/adapter","ember-data/system/map","exports"],
1079
+ function(__dependency1__, __dependency2__, __exports__) {
1064
1080
  "use strict";
1065
1081
  /**
1066
1082
  @module ember-data
@@ -1068,6 +1084,7 @@ define("ember-data/adapters/rest_adapter",
1068
1084
 
1069
1085
  var Adapter = __dependency1__.Adapter;
1070
1086
  var InvalidError = __dependency1__.InvalidError;
1087
+ var MapWithDefault = __dependency2__.MapWithDefault;
1071
1088
  var get = Ember.get;
1072
1089
  var forEach = Ember.ArrayPolyfills.forEach;
1073
1090
 
@@ -1267,6 +1284,9 @@ define("ember-data/adapters/rest_adapter",
1267
1284
 
1268
1285
  will also send a request to: `GET /comments?ids[]=1&ids[]=2`
1269
1286
 
1287
+ Note: Requests coalescing rely on URL building strategy. So if you override `buildUrl` in your app
1288
+ `groupRecordsForFindMany` more likely should be overriden as well in order for coalescing to work.
1289
+
1270
1290
  @property coalesceFindRequests
1271
1291
  @type {boolean}
1272
1292
  */
@@ -1595,7 +1615,7 @@ define("ember-data/adapters/rest_adapter",
1595
1615
  //We might get passed in an array of ids from findMany
1596
1616
  //in which case we don't want to modify the url, as the
1597
1617
  //ids will be passed in through a query param
1598
- if (id && !Ember.isArray(id)) { url.push(id); }
1618
+ if (id && !Ember.isArray(id)) { url.push(encodeURIComponent(id)); }
1599
1619
 
1600
1620
  if (prefix) { url.unshift(prefix); }
1601
1621
 
@@ -1680,7 +1700,7 @@ define("ember-data/adapters/rest_adapter",
1680
1700
  loaded separately by `findMany`.
1681
1701
  */
1682
1702
  groupRecordsForFindMany: function (store, records) {
1683
- var groups = Ember.MapWithDefault.create({defaultValue: function(){return [];}});
1703
+ var groups = MapWithDefault.create({defaultValue: function(){return [];}});
1684
1704
  var adapter = this;
1685
1705
 
1686
1706
  forEach.call(records, function(record){
@@ -1710,7 +1730,7 @@ define("ember-data/adapters/rest_adapter",
1710
1730
  }
1711
1731
 
1712
1732
  var groupsArray = [];
1713
- groups.forEach(function(key, group){
1733
+ groups.forEach(function(group, key){
1714
1734
  // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
1715
1735
  var maxUrlLength = 2048;
1716
1736
  var splitGroups = splitGroupToFitInUrl(group, maxUrlLength);
@@ -1929,11 +1949,11 @@ define("ember-data/core",
1929
1949
  /**
1930
1950
  @property VERSION
1931
1951
  @type String
1932
- @default '1.0.0-beta.10'
1952
+ @default '1.0.0-beta.11'
1933
1953
  @static
1934
1954
  */
1935
1955
  DS = Ember.Namespace.create({
1936
- VERSION: '1.0.0-beta.10'
1956
+ VERSION: '1.0.0-beta.11'
1937
1957
  });
1938
1958
 
1939
1959
  if (Ember.libraries) {
@@ -2052,7 +2072,8 @@ define("ember-data/ext/date",
2052
2072
 
2053
2073
  /**
2054
2074
  @method parse
2055
- @param date
2075
+ @param {Date} date
2076
+ @return {Number} timestamp
2056
2077
  */
2057
2078
  Ember.Date.parse = function (date) {
2058
2079
  var timestamp, struct, minutesOffset = 0;
@@ -2224,21 +2245,24 @@ define("ember-data/serializers/embedded_records_mixin",
2224
2245
  ```js
2225
2246
  App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
2226
2247
  attrs: {
2227
- author: {embedded: 'always'},
2228
- comments: {serialize: 'ids'}
2248
+ author: { embedded: 'always' },
2249
+ comments: { serialize: 'ids' }
2229
2250
  }
2230
- })
2251
+ });
2231
2252
  ```
2232
- Note that this use of `{embedded: 'always'}` is unrelated to
2233
- the `{embedded: 'always'}` that is defined as an option on `DS.attr` as part of
2253
+ Note that this use of `{ embedded: 'always' }` is unrelated to
2254
+ the `{ embedded: 'always' }` that is defined as an option on `DS.attr` as part of
2234
2255
  defining a model while working with the ActiveModelSerializer. Nevertheless,
2235
- using `{embedded: 'always'}` as an option to DS.attr is not a valid way to setup
2256
+ using `{ embedded: 'always' }` as an option to DS.attr is not a valid way to setup
2236
2257
  embedded records.
2237
2258
 
2238
- The `attrs` option for a resource `{embedded: 'always'}` is shorthand for:
2259
+ The `attrs` option for a resource `{ embedded: 'always' }` is shorthand for:
2239
2260
 
2240
2261
  ```js
2241
- {serialize: 'records', deserialize: 'records'}
2262
+ {
2263
+ serialize: 'records',
2264
+ deserialize: 'records'
2265
+ }
2242
2266
  ```
2243
2267
 
2244
2268
  ### Configuring Attrs
@@ -2262,8 +2286,8 @@ define("ember-data/serializers/embedded_records_mixin",
2262
2286
  If you do not overwrite `attrs` for a specific relationship, the `EmbeddedRecordsMixin`
2263
2287
  will behave in the following way:
2264
2288
 
2265
- BelongsTo: `{serialize:'id', deserialize:'id'}`
2266
- HasMany: `{serialize:false, deserialize:'ids'}`
2289
+ BelongsTo: `{ serialize: 'id', deserialize: 'id' }`
2290
+ HasMany: `{ serialize: false, deserialize: 'ids' }`
2267
2291
 
2268
2292
  ### Model Relationships
2269
2293
 
@@ -3259,8 +3283,9 @@ define("ember-data/serializers/json_serializer",
3259
3283
  payloadKey = this.keyForRelationship(key, "belongsTo");
3260
3284
  }
3261
3285
 
3262
- if (isNone(belongsTo)) {
3263
- json[payloadKey] = belongsTo;
3286
+ //Need to check whether the id is there for new&async records
3287
+ if (isNone(belongsTo) || isNone(get(belongsTo, 'id'))) {
3288
+ json[payloadKey] = null;
3264
3289
  } else {
3265
3290
  json[payloadKey] = get(belongsTo, 'id');
3266
3291
  }
@@ -3768,7 +3793,7 @@ define("ember-data/serializers/rest_serializer",
3768
3793
  @namespace DS
3769
3794
  @extends DS.JSONSerializer
3770
3795
  */
3771
- __exports__["default"] = JSONSerializer.extend({
3796
+ var RESTSerializer = JSONSerializer.extend({
3772
3797
  /**
3773
3798
  If you want to do normalizations specific to some part of the payload, you
3774
3799
  can specify those under `normalizeHash`.
@@ -3981,6 +4006,10 @@ define("ember-data/serializers/rest_serializer",
3981
4006
 
3982
4007
  for (var prop in payload) {
3983
4008
  var typeName = this.typeForRoot(prop);
4009
+ if (!store.modelFactoryFor(typeName)){
4010
+ Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
4011
+ continue;
4012
+ }
3984
4013
  var type = store.modelFor(typeName);
3985
4014
  var isPrimary = type.typeKey === primaryTypeName;
3986
4015
  var value = payload[prop];
@@ -4134,6 +4163,10 @@ define("ember-data/serializers/rest_serializer",
4134
4163
  }
4135
4164
 
4136
4165
  var typeName = this.typeForRoot(typeKey);
4166
+ if (!store.modelFactoryFor(typeName)) {
4167
+ Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
4168
+ continue;
4169
+ }
4137
4170
  var type = store.modelFor(typeName);
4138
4171
  var typeSerializer = store.serializerFor(type);
4139
4172
  var isPrimary = (!forcedSecondary && (type.typeKey === primaryTypeName));
@@ -4189,6 +4222,10 @@ define("ember-data/serializers/rest_serializer",
4189
4222
 
4190
4223
  for (var prop in payload) {
4191
4224
  var typeName = this.typeForRoot(prop);
4225
+ if (!store.modelFactoryFor(typeName, prop)){
4226
+ Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
4227
+ continue;
4228
+ }
4192
4229
  var type = store.modelFor(typeName);
4193
4230
  var typeSerializer = store.serializerFor(type);
4194
4231
 
@@ -4389,8 +4426,9 @@ define("ember-data/serializers/rest_serializer",
4389
4426
  ```
4390
4427
 
4391
4428
  @method serialize
4392
- @param record
4393
- @param options
4429
+ @param {subclass of DS.Model} record
4430
+ @param {Object} options
4431
+ @return {Object} json
4394
4432
  */
4395
4433
  serialize: function(record, options) {
4396
4434
  return this._super.apply(this, arguments);
@@ -4443,6 +4481,16 @@ define("ember-data/serializers/rest_serializer",
4443
4481
  }
4444
4482
  }
4445
4483
  });
4484
+
4485
+ Ember.runInDebug(function(){
4486
+ RESTSerializer.reopen({
4487
+ warnMessageNoModelForKey: function(prop, typeKey){
4488
+ return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + typeKey + '" (resolved model name using ' + this.constructor.toString() + '.typeForRoot("' + prop + '"))';
4489
+ }
4490
+ });
4491
+ });
4492
+
4493
+ __exports__["default"] = RESTSerializer;
4446
4494
  });
4447
4495
  define("ember-data/setup-container",
4448
4496
  ["ember-data/initializers/store","ember-data/initializers/transforms","ember-data/initializers/store_injections","ember-data/initializers/data_adapter","activemodel-adapter/setup-container","exports"],
@@ -5038,7 +5086,7 @@ define("ember-data/system/debug/debug_adapter",
5038
5086
  }];
5039
5087
  var count = 0;
5040
5088
  var self = this;
5041
- get(type, 'attributes').forEach(function(name, meta) {
5089
+ get(type, 'attributes').forEach(function(meta, name) {
5042
5090
  if (count++ > self.attributeLimit) { return false; }
5043
5091
  var desc = capitalize(underscore(name).replace('_', ' '));
5044
5092
  columns.push({ name: name, desc: desc });
@@ -5195,6 +5243,101 @@ define("ember-data/system/debug/debug_info",
5195
5243
 
5196
5244
  __exports__["default"] = Model;
5197
5245
  });
5246
+ define("ember-data/system/map",
5247
+ ["exports"],
5248
+ function(__exports__) {
5249
+ "use strict";
5250
+ /**
5251
+ * Polyfill Ember.Map behavior for Ember <= 1.7
5252
+ * This can probably be removed before 1.0 final
5253
+ */
5254
+ var mapForEach, deleteFn;
5255
+
5256
+ function OrderedSet(){
5257
+ Ember.OrderedSet.apply(this, arguments);
5258
+ }
5259
+
5260
+ function Map() {
5261
+ Ember.Map.apply(this, arguments);
5262
+ }
5263
+
5264
+ function MapWithDefault(){
5265
+ Ember.MapWithDefault.apply(this, arguments);
5266
+ }
5267
+
5268
+ var testMap = Ember.Map.create();
5269
+ testMap.set('key', 'value');
5270
+
5271
+ var usesOldBehavior = false;
5272
+
5273
+ testMap.forEach(function(value, key){
5274
+ usesOldBehavior = value === 'key' && key === 'value';
5275
+ });
5276
+
5277
+ Map.prototype = Object.create(Ember.Map.prototype);
5278
+ MapWithDefault.prototype = Object.create(Ember.MapWithDefault.prototype);
5279
+ OrderedSet.prototype = Object.create(Ember.OrderedSet.prototype);
5280
+
5281
+ OrderedSet.create = function(){
5282
+ return new OrderedSet();
5283
+ };
5284
+
5285
+ /**
5286
+ * returns a function that calls the original
5287
+ * callback function in the correct order.
5288
+ * if we are in pre-Ember.1.8 land, Map/MapWithDefault
5289
+ * forEach calls with key, value, in that order.
5290
+ * >= 1.8 forEach is called with the order value, key as per
5291
+ * the ES6 spec.
5292
+ */
5293
+ function translate(valueKeyOrderedCallback){
5294
+ return function(key, value){
5295
+ valueKeyOrderedCallback.call(this, value, key);
5296
+ };
5297
+ }
5298
+
5299
+ // old, non ES6 compliant behavior
5300
+ if (usesOldBehavior){
5301
+ mapForEach = function(callback, thisArg){
5302
+ this.__super$forEach(translate(callback), thisArg);
5303
+ };
5304
+
5305
+ /* alias to remove */
5306
+ deleteFn = function(thing){
5307
+ this.remove(thing);
5308
+ };
5309
+
5310
+ Map.prototype.__super$forEach = Ember.Map.prototype.forEach;
5311
+ Map.prototype.forEach = mapForEach;
5312
+ Map.prototype["delete"] = deleteFn;
5313
+
5314
+ MapWithDefault.prototype.forEach = mapForEach;
5315
+ MapWithDefault.prototype.__super$forEach = Ember.MapWithDefault.prototype.forEach;
5316
+ MapWithDefault.prototype["delete"] = deleteFn;
5317
+
5318
+ OrderedSet.prototype["delete"] = deleteFn;
5319
+ }
5320
+
5321
+ MapWithDefault.constructor = MapWithDefault;
5322
+ Map.constructor = Map;
5323
+
5324
+ MapWithDefault.create = function(options){
5325
+ if (options) {
5326
+ return new MapWithDefault(options);
5327
+ } else {
5328
+ return new Map();
5329
+ }
5330
+ };
5331
+
5332
+ Map.create = function(){
5333
+ return new this.constructor();
5334
+ };
5335
+
5336
+ __exports__["default"] = Map;
5337
+ __exports__.Map = Map;
5338
+ __exports__.MapWithDefault = MapWithDefault;
5339
+ __exports__.OrderedSet = OrderedSet;
5340
+ });
5198
5341
  define("ember-data/system/model",
5199
5342
  ["ember-data/system/model/model","ember-data/system/model/attributes","ember-data/system/model/states","ember-data/system/model/errors","exports"],
5200
5343
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
@@ -5214,10 +5357,11 @@ define("ember-data/system/model",
5214
5357
  __exports__.Errors = Errors;
5215
5358
  });
5216
5359
  define("ember-data/system/model/attributes",
5217
- ["ember-data/system/model/model","exports"],
5218
- function(__dependency1__, __exports__) {
5360
+ ["ember-data/system/model/model","ember-data/system/map","exports"],
5361
+ function(__dependency1__, __dependency2__, __exports__) {
5219
5362
  "use strict";
5220
5363
  var Model = __dependency1__["default"];
5364
+ var Map = __dependency2__.Map;
5221
5365
 
5222
5366
  /**
5223
5367
  @module ember-data
@@ -5263,7 +5407,7 @@ define("ember-data/system/model/attributes",
5263
5407
  @readOnly
5264
5408
  */
5265
5409
  attributes: Ember.computed(function() {
5266
- var map = Ember.Map.create();
5410
+ var map = Map.create();
5267
5411
 
5268
5412
  this.eachComputedProperty(function(name, meta) {
5269
5413
  if (meta.isAttribute) {
@@ -5309,7 +5453,7 @@ define("ember-data/system/model/attributes",
5309
5453
  @readOnly
5310
5454
  */
5311
5455
  transformedAttributes: Ember.computed(function() {
5312
- var map = Ember.Map.create();
5456
+ var map = Map.create();
5313
5457
 
5314
5458
  this.eachAttribute(function(key, meta) {
5315
5459
  if (meta.type) {
@@ -5362,7 +5506,7 @@ define("ember-data/system/model/attributes",
5362
5506
  @static
5363
5507
  */
5364
5508
  eachAttribute: function(callback, binding) {
5365
- get(this, 'attributes').forEach(function(name, meta) {
5509
+ get(this, 'attributes').forEach(function(meta, name) {
5366
5510
  callback.call(binding, name, meta);
5367
5511
  }, binding);
5368
5512
  },
@@ -5410,7 +5554,7 @@ define("ember-data/system/model/attributes",
5410
5554
  @static
5411
5555
  */
5412
5556
  eachTransformedAttribute: function(callback, binding) {
5413
- get(this, 'transformedAttributes').forEach(function(name, type) {
5557
+ get(this, 'transformedAttributes').forEach(function(type, name) {
5414
5558
  callback.call(binding, name, type);
5415
5559
  });
5416
5560
  }
@@ -5524,13 +5668,15 @@ define("ember-data/system/model/attributes",
5524
5668
  };
5525
5669
  });
5526
5670
  define("ember-data/system/model/errors",
5527
- ["exports"],
5528
- function(__exports__) {
5671
+ ["ember-data/system/map","exports"],
5672
+ function(__dependency1__, __exports__) {
5529
5673
  "use strict";
5530
5674
  var get = Ember.get;
5531
5675
  var isEmpty = Ember.isEmpty;
5532
5676
  var map = Ember.EnumerableUtils.map;
5533
5677
 
5678
+ var MapWithDefault = __dependency1__.MapWithDefault;
5679
+
5534
5680
  /**
5535
5681
  @module ember-data
5536
5682
  */
@@ -5627,7 +5773,7 @@ define("ember-data/system/model/errors",
5627
5773
  */
5628
5774
  errorsByAttributeName: Ember.reduceComputed("content", {
5629
5775
  initialValue: function() {
5630
- return Ember.MapWithDefault.create({
5776
+ return MapWithDefault.create({
5631
5777
  defaultValue: function() {
5632
5778
  return Ember.A();
5633
5779
  }
@@ -6319,6 +6465,27 @@ define("ember-data/system/model/model",
6319
6465
  this._attributes = {};
6320
6466
  this._inFlightAttributes = {};
6321
6467
  this._relationships = {};
6468
+ /*
6469
+ implicit relationships are relationship which have not been declared but the inverse side exists on
6470
+ another record somewhere
6471
+ For example if there was
6472
+ ```
6473
+ App.Comment = DS.Model.extend({
6474
+ name: DS.attr()
6475
+ })
6476
+ ```
6477
+ but there is also
6478
+ ```
6479
+ App.Post = DS.Model.extend({
6480
+ name: DS.attr(),
6481
+ comments: DS.hasMany('comment')
6482
+ })
6483
+ ```
6484
+
6485
+ would have a implicit post relationship in order to be do things like remove ourselves from the post
6486
+ when we are deleted
6487
+ */
6488
+ this._implicitRelationships = Object.create(null);
6322
6489
  var model = this;
6323
6490
  //TODO Move into a getter for better perf
6324
6491
  this.constructor.eachRelationship(function(key, descriptor) {
@@ -6516,6 +6683,27 @@ define("ember-data/system/model/model",
6516
6683
  }, this);
6517
6684
  },
6518
6685
 
6686
+ disconnectRelationships: function() {
6687
+ this.eachRelationship(function(name, relationship) {
6688
+ this._relationships[name].disconnect();
6689
+ }, this);
6690
+ var model = this;
6691
+ forEach.call(Ember.keys(this._implicitRelationships), function(key) {
6692
+ model._implicitRelationships[key].disconnect();
6693
+ });
6694
+ },
6695
+
6696
+ reconnectRelationships: function() {
6697
+ this.eachRelationship(function(name, relationship) {
6698
+ this._relationships[name].reconnect();
6699
+ }, this);
6700
+ var model = this;
6701
+ forEach.call(Ember.keys(this._implicitRelationships), function(key) {
6702
+ model._implicitRelationships[key].reconnect();
6703
+ });
6704
+ },
6705
+
6706
+
6519
6707
  /**
6520
6708
  @method updateRecordArrays
6521
6709
  @private
@@ -6737,6 +6925,13 @@ define("ember-data/system/model/model",
6737
6925
  set(this, 'isError', false);
6738
6926
  }
6739
6927
 
6928
+ //Eventually rollback will always work for relationships
6929
+ //For now we support it only out of deleted state, because we
6930
+ //have an explicit way of knowing when the server acked the relationship change
6931
+ if (get(this, 'isDeleted')) {
6932
+ this.reconnectRelationships();
6933
+ }
6934
+
6740
6935
  if (!get(this, 'isValid')) {
6741
6936
  this._inFlightAttributes = {};
6742
6937
  }
@@ -6752,7 +6947,7 @@ define("ember-data/system/model/model",
6752
6947
 
6753
6948
  /**
6754
6949
  Save the record and persist any changes to the record to an
6755
- extenal source via the adapter.
6950
+ external source via the adapter.
6756
6951
 
6757
6952
  Example
6758
6953
 
@@ -6819,7 +7014,9 @@ define("ember-data/system/model/model",
6819
7014
  }, function(reason) {
6820
7015
  record.set('isError', true);
6821
7016
  throw reason;
6822
- }, "DS: Model#reload complete, update flags");
7017
+ }, "DS: Model#reload complete, update flags")['finally'](function () {
7018
+ record.updateRecordArrays();
7019
+ });
6823
7020
 
6824
7021
  return PromiseObject.create({
6825
7022
  promise: promise
@@ -6875,15 +7072,32 @@ define("ember-data/system/model/model",
6875
7072
 
6876
7073
  @method trigger
6877
7074
  @private
6878
- @param name
7075
+ @param {String} name
6879
7076
  */
6880
- trigger: function(name) {
6881
- Ember.tryInvoke(this, name, [].slice.call(arguments, 1));
7077
+ trigger: function() {
7078
+ var length = arguments.length;
7079
+ var args = new Array(length - 1);
7080
+ var name = arguments[0];
7081
+
7082
+ for (var i = 1; i < length; i++ ){
7083
+ args[i - 1] = arguments[i];
7084
+ }
7085
+
7086
+ Ember.tryInvoke(this, name, args);
6882
7087
  this._super.apply(this, arguments);
6883
7088
  },
6884
7089
 
6885
7090
  triggerLater: function() {
6886
- if (this._deferredTriggers.push(arguments) !== 1) { return; }
7091
+ var length = arguments.length;
7092
+ var args = new Array(length);
7093
+
7094
+ for (var i = 0; i < length; i++ ){
7095
+ args[i] = arguments[i];
7096
+ }
7097
+
7098
+ if (this._deferredTriggers.push(args) !== 1) {
7099
+ return;
7100
+ }
6887
7101
  Ember.run.schedule('actions', this, '_triggerDeferredTriggers');
6888
7102
  },
6889
7103
 
@@ -7267,7 +7481,7 @@ define("ember-data/system/model/states",
7267
7481
  // EVENTS
7268
7482
  deleteRecord: function(record) {
7269
7483
  record.transitionTo('deleted.uncommitted');
7270
- record.clearRelationships();
7484
+ record.disconnectRelationships();
7271
7485
  },
7272
7486
 
7273
7487
  didSetProperty: function(record, context) {
@@ -7348,7 +7562,7 @@ define("ember-data/system/model/states",
7348
7562
  });
7349
7563
 
7350
7564
  createdState.uncommitted.deleteRecord = function(record) {
7351
- record.clearRelationships();
7565
+ record.disconnectRelationships();
7352
7566
  record.transitionTo('deleted.saved');
7353
7567
  };
7354
7568
 
@@ -7367,7 +7581,7 @@ define("ember-data/system/model/states",
7367
7581
 
7368
7582
  updatedState.uncommitted.deleteRecord = function(record) {
7369
7583
  record.transitionTo('deleted.uncommitted');
7370
- record.clearRelationships();
7584
+ record.disconnectRelationships();
7371
7585
  };
7372
7586
 
7373
7587
  var RootState = {
@@ -7508,7 +7722,7 @@ define("ember-data/system/model/states",
7508
7722
 
7509
7723
  deleteRecord: function(record) {
7510
7724
  record.transitionTo('deleted.uncommitted');
7511
- record.clearRelationships();
7725
+ record.disconnectRelationships();
7512
7726
  },
7513
7727
 
7514
7728
  unloadRecord: function(record) {
@@ -7665,6 +7879,7 @@ define("ember-data/system/promise_proxies",
7665
7879
  function(__exports__) {
7666
7880
  "use strict";
7667
7881
  var Promise = Ember.RSVP.Promise;
7882
+ var get = Ember.get;
7668
7883
 
7669
7884
  /**
7670
7885
  A `PromiseArray` is an object that acts like both an `Ember.Array`
@@ -7740,14 +7955,38 @@ define("ember-data/system/promise_proxies",
7740
7955
  });
7741
7956
  };
7742
7957
 
7958
+ /**
7959
+ A PromiseManyArray is a PromiseArray that also proxies certain method calls
7960
+ to the underlying manyArray.
7961
+ Right now we proxy:
7962
+ `reload()`
7963
+ */
7964
+
7965
+ var PromiseManyArray = PromiseArray.extend({
7966
+ reload: function() {
7967
+ //I don't think this should ever happen right now, but worth guarding if we refactor the async relationships
7968
+ Ember.assert('You are trying to reload an async manyArray before it has been created', get(this, 'content'));
7969
+ return get(this, 'content').reload();
7970
+ }
7971
+ });
7972
+
7973
+ var promiseManyArray = function(promise, label) {
7974
+ return PromiseManyArray.create({
7975
+ promise: Promise.resolve(promise, label)
7976
+ });
7977
+ };
7978
+
7979
+
7743
7980
  __exports__.PromiseArray = PromiseArray;
7744
7981
  __exports__.PromiseObject = PromiseObject;
7982
+ __exports__.PromiseManyArray = PromiseManyArray;
7745
7983
  __exports__.promiseArray = promiseArray;
7746
7984
  __exports__.promiseObject = promiseObject;
7985
+ __exports__.promiseManyArray = promiseManyArray;
7747
7986
  });
7748
7987
  define("ember-data/system/record_array_manager",
7749
- ["ember-data/system/record_arrays","exports"],
7750
- function(__dependency1__, __exports__) {
7988
+ ["ember-data/system/record_arrays","ember-data/system/map","exports"],
7989
+ function(__dependency1__, __dependency2__, __exports__) {
7751
7990
  "use strict";
7752
7991
  /**
7753
7992
  @module ember-data
@@ -7757,6 +7996,8 @@ define("ember-data/system/record_array_manager",
7757
7996
  var FilteredRecordArray = __dependency1__.FilteredRecordArray;
7758
7997
  var AdapterPopulatedRecordArray = __dependency1__.AdapterPopulatedRecordArray;
7759
7998
  var ManyArray = __dependency1__.ManyArray;
7999
+ var MapWithDefault = __dependency2__.MapWithDefault;
8000
+ var OrderedSet = __dependency2__.OrderedSet;
7760
8001
  var get = Ember.get;
7761
8002
  var forEach = Ember.EnumerableUtils.forEach;
7762
8003
 
@@ -7768,7 +8009,7 @@ define("ember-data/system/record_array_manager",
7768
8009
  */
7769
8010
  __exports__["default"] = Ember.Object.extend({
7770
8011
  init: function() {
7771
- this.filteredRecordArrays = Ember.MapWithDefault.create({
8012
+ this.filteredRecordArrays = MapWithDefault.create({
7772
8013
  defaultValue: function() { return []; }
7773
8014
  });
7774
8015
 
@@ -7783,7 +8024,7 @@ define("ember-data/system/record_array_manager",
7783
8024
  },
7784
8025
 
7785
8026
  recordArraysForRecord: function(record) {
7786
- record._recordArrays = record._recordArrays || Ember.OrderedSet.create();
8027
+ record._recordArrays = record._recordArrays || OrderedSet.create();
7787
8028
  return record._recordArrays;
7788
8029
  },
7789
8030
 
@@ -7816,9 +8057,11 @@ define("ember-data/system/record_array_manager",
7816
8057
 
7817
8058
  if (!recordArrays) { return; }
7818
8059
 
7819
- forEach(recordArrays, function(array) {
8060
+ recordArrays.forEach(function(array){
7820
8061
  array.removeRecord(record);
7821
8062
  });
8063
+
8064
+ record._recordArrays = null;
7822
8065
  },
7823
8066
 
7824
8067
  _recordWasChanged: function (record) {
@@ -7870,7 +8113,7 @@ define("ember-data/system/record_array_manager",
7870
8113
  recordArrays.add(array);
7871
8114
  }
7872
8115
  } else if (!shouldBeInArray) {
7873
- recordArrays.remove(array);
8116
+ recordArrays["delete"](array);
7874
8117
  array.removeRecord(record);
7875
8118
  }
7876
8119
  },
@@ -7883,9 +8126,9 @@ define("ember-data/system/record_array_manager",
7883
8126
  method is invoked when the filter is created in th first place.
7884
8127
 
7885
8128
  @method updateFilter
7886
- @param array
7887
- @param type
7888
- @param filter
8129
+ @param {Array} array
8130
+ @param {String} type
8131
+ @param {Function} filter
7889
8132
  */
7890
8133
  updateFilter: function(array, type, filter) {
7891
8134
  var typeMap = this.store.typeMapFor(type);
@@ -8259,22 +8502,6 @@ define("ember-data/system/record_arrays/many_array",
8259
8502
  this._super.apply(this, arguments);
8260
8503
  },
8261
8504
 
8262
- /**
8263
- The property name of the relationship
8264
-
8265
- @property {String} name
8266
- @private
8267
- */
8268
- name: null,
8269
-
8270
- /**
8271
- The record to which this relationship belongs.
8272
-
8273
- @property {DS.Model} owner
8274
- @private
8275
- */
8276
- owner: null,
8277
-
8278
8505
  /**
8279
8506
  `true` if the relationship is polymorphic, `false` otherwise.
8280
8507
 
@@ -8337,6 +8564,13 @@ define("ember-data/system/record_arrays/many_array",
8337
8564
  this.get('relationship').addRecords(objects, idx);
8338
8565
  }
8339
8566
  },
8567
+ /**
8568
+ @method reload
8569
+ @public
8570
+ */
8571
+ reload: function() {
8572
+ return this.relationship.reload();
8573
+ },
8340
8574
 
8341
8575
  /**
8342
8576
  Create a child record within the owner
@@ -8557,7 +8791,7 @@ define("ember-data/system/record_arrays/record_array",
8557
8791
  var recordArrays = record._recordArrays;
8558
8792
 
8559
8793
  if (recordArrays) {
8560
- recordArrays.remove(array);
8794
+ recordArrays["delete"](array);
8561
8795
  }
8562
8796
  });
8563
8797
  },
@@ -8695,7 +8929,11 @@ define("ember-data/system/relationships/belongs_to",
8695
8929
  if ( value === undefined ) {
8696
8930
  value = null;
8697
8931
  }
8698
- this._relationships[key].setRecord(value);
8932
+ if (value && value.then) {
8933
+ this._relationships[key].setRecordPromise(value);
8934
+ } else {
8935
+ this._relationships[key].setRecord(value);
8936
+ }
8699
8937
  }
8700
8938
 
8701
8939
  return this._relationships[key].getRecord();
@@ -8722,14 +8960,17 @@ define("ember-data/system/relationships/belongs_to",
8722
8960
  __exports__["default"] = belongsTo;
8723
8961
  });
8724
8962
  define("ember-data/system/relationships/ext",
8725
- ["ember-data/system/relationship-meta","ember-data/system/model"],
8726
- function(__dependency1__, __dependency2__) {
8963
+ ["ember-data/system/relationship-meta","ember-data/system/model","ember-data/system/map"],
8964
+ function(__dependency1__, __dependency2__, __dependency3__) {
8727
8965
  "use strict";
8728
8966
  var typeForRelationshipMeta = __dependency1__.typeForRelationshipMeta;
8729
8967
  var relationshipFromMeta = __dependency1__.relationshipFromMeta;
8730
8968
  var Model = __dependency2__.Model;
8969
+ var Map = __dependency3__.Map;
8970
+ var MapWithDefault = __dependency3__.MapWithDefault;
8731
8971
 
8732
8972
  var get = Ember.get;
8973
+ var filter = Ember.ArrayPolyfills.filter;
8733
8974
 
8734
8975
  /**
8735
8976
  @module ember-data
@@ -8768,9 +9009,9 @@ define("ember-data/system/relationships/ext",
8768
9009
  property returned by `DS.belongsTo` as the value.
8769
9010
 
8770
9011
  @method didDefineProperty
8771
- @param proto
8772
- @param key
8773
- @param value
9012
+ @param {Object} proto
9013
+ @param {String} key
9014
+ @param {Ember.ComputedProperty} value
8774
9015
  */
8775
9016
  didDefineProperty: function(proto, key, value) {
8776
9017
  // Check if the value being set is a computed property.
@@ -8804,6 +9045,7 @@ define("ember-data/system/relationships/ext",
8804
9045
  */
8805
9046
 
8806
9047
  Model.reopenClass({
9048
+
8807
9049
  /**
8808
9050
  For a given relationship name, returns the model type of the relationship.
8809
9051
 
@@ -8827,17 +9069,59 @@ define("ember-data/system/relationships/ext",
8827
9069
  return relationship && relationship.type;
8828
9070
  },
8829
9071
 
9072
+ inverseMap: Ember.computed(function() {
9073
+ return Object.create(null);
9074
+ }),
9075
+
9076
+ /*
9077
+ Find the relationship which is the inverse of the one asked for.
9078
+
9079
+ For example, if you define models like this:
9080
+
9081
+ ```javascript
9082
+ App.Post = DS.Model.extend({
9083
+ comments: DS.hasMany('message')
9084
+ });
9085
+
9086
+ App.Message = DS.Model.extend({
9087
+ owner: DS.belongsTo('post')
9088
+ });
9089
+ ```
9090
+
9091
+ App.Post.inverseFor('comments') -> {type: App.Message, name:'owner', kind:'belongsTo'}
9092
+ App.Message.inverseFor('owner') -> {type: App.Post, name:'comments', kind:'hasMany'}
9093
+
9094
+ @method inverseFor
9095
+ @static
9096
+ @param {String} name the name of the relationship
9097
+ @return {Object} the inverse relationship, or null
9098
+ */
8830
9099
  inverseFor: function(name) {
8831
- var inverseType = this.typeForRelationship(name);
9100
+ var inverseMap = get(this, 'inverseMap');
9101
+ if (inverseMap[name]) {
9102
+ return inverseMap[name];
9103
+ } else {
9104
+ var inverse = this._findInverseFor(name);
9105
+ inverseMap[name] = inverse;
9106
+ return inverse;
9107
+ }
9108
+ },
8832
9109
 
8833
- if (!inverseType) { return null; }
9110
+ //Calculate the inverse, ignoring the cache
9111
+ _findInverseFor: function(name) {
8834
9112
 
8835
- var options = this.metaForProperty(name).options;
9113
+ var inverseType = this.typeForRelationship(name);
9114
+ if (!inverseType) {
9115
+ return null;
9116
+ }
8836
9117
 
9118
+ //If inverse is manually specified to be null, like `comments: DS.hasMany('message', {inverse: null})`
9119
+ var options = this.metaForProperty(name).options;
8837
9120
  if (options.inverse === null) { return null; }
8838
9121
 
8839
9122
  var inverseName, inverseKind, inverse;
8840
9123
 
9124
+ //If inverse is specified manually, return the inverse
8841
9125
  if (options.inverse) {
8842
9126
  inverseName = options.inverse;
8843
9127
  inverse = Ember.get(inverseType, 'relationshipsByName').get(inverseName);
@@ -8847,10 +9131,24 @@ define("ember-data/system/relationships/ext",
8847
9131
 
8848
9132
  inverseKind = inverse.kind;
8849
9133
  } else {
9134
+ //No inverse was specified manually, we need to use a heuristic to guess one
8850
9135
  var possibleRelationships = findPossibleInverses(this, inverseType);
8851
9136
 
8852
9137
  if (possibleRelationships.length === 0) { return null; }
8853
9138
 
9139
+ var filteredRelationships = filter.call(possibleRelationships, function(possibleRelationship) {
9140
+ var optionsForRelationship = inverseType.metaForProperty(possibleRelationship.name).options;
9141
+ return name === optionsForRelationship.inverse;
9142
+ });
9143
+
9144
+ Ember.assert("You defined the '" + name + "' relationship on " + this + ", but you defined the inverse relationships of type " +
9145
+ inverseType.toString() + " multiple times. Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses",
9146
+ filteredRelationships.length < 2);
9147
+
9148
+ if (filteredRelationships.length === 1 ) {
9149
+ possibleRelationships = filteredRelationships;
9150
+ }
9151
+
8854
9152
  Ember.assert("You defined the '" + name + "' relationship on " + this + ", but multiple possible inverse relationships of type " +
8855
9153
  this + " were found on " + inverseType + ". Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses",
8856
9154
  possibleRelationships.length === 1);
@@ -8859,17 +9157,29 @@ define("ember-data/system/relationships/ext",
8859
9157
  inverseKind = possibleRelationships[0].kind;
8860
9158
  }
8861
9159
 
8862
- function findPossibleInverses(type, inverseType, possibleRelationships) {
8863
- possibleRelationships = possibleRelationships || [];
9160
+ function findPossibleInverses(type, inverseType, relationshipsSoFar) {
9161
+ var possibleRelationships = relationshipsSoFar || [];
8864
9162
 
8865
9163
  var relationshipMap = get(inverseType, 'relationships');
8866
9164
  if (!relationshipMap) { return; }
8867
9165
 
8868
9166
  var relationships = relationshipMap.get(type);
9167
+
9168
+ relationships = filter.call(relationships, function(relationship) {
9169
+ var optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
9170
+
9171
+ if (!optionsForRelationship.inverse){
9172
+ return true;
9173
+ }
9174
+
9175
+ return name === optionsForRelationship.inverse;
9176
+ });
9177
+
8869
9178
  if (relationships) {
8870
- possibleRelationships.push.apply(possibleRelationships, relationshipMap.get(type));
9179
+ possibleRelationships.push.apply(possibleRelationships, relationships);
8871
9180
  }
8872
9181
 
9182
+ //Recurse to support polymorphism
8873
9183
  if (type.superclass) {
8874
9184
  findPossibleInverses(type.superclass, inverseType, possibleRelationships);
8875
9185
  }
@@ -8918,7 +9228,7 @@ define("ember-data/system/relationships/ext",
8918
9228
  @readOnly
8919
9229
  */
8920
9230
  relationships: Ember.computed(function() {
8921
- var map = new Ember.MapWithDefault({
9231
+ var map = new MapWithDefault({
8922
9232
  defaultValue: function() { return []; }
8923
9233
  });
8924
9234
 
@@ -9068,7 +9378,7 @@ define("ember-data/system/relationships/ext",
9068
9378
  @readOnly
9069
9379
  */
9070
9380
  relationshipsByName: Ember.computed(function() {
9071
- var map = Ember.Map.create();
9381
+ var map = Map.create();
9072
9382
 
9073
9383
  this.eachComputedProperty(function(name, meta) {
9074
9384
  if (meta.isRelationship) {
@@ -9118,7 +9428,7 @@ define("ember-data/system/relationships/ext",
9118
9428
  @readOnly
9119
9429
  */
9120
9430
  fields: Ember.computed(function() {
9121
- var map = Ember.Map.create();
9431
+ var map = Map.create();
9122
9432
 
9123
9433
  this.eachComputedProperty(function(name, meta) {
9124
9434
  if (meta.isRelationship) {
@@ -9142,7 +9452,7 @@ define("ember-data/system/relationships/ext",
9142
9452
  @param {any} binding the value to which the callback's `this` should be bound
9143
9453
  */
9144
9454
  eachRelationship: function(callback, binding) {
9145
- get(this, 'relationshipsByName').forEach(function(name, relationship) {
9455
+ get(this, 'relationshipsByName').forEach(function(relationship, name) {
9146
9456
  callback.call(binding, name, relationship);
9147
9457
  });
9148
9458
  },
@@ -9346,14 +9656,15 @@ define("ember-data/system/relationships/has_many",
9346
9656
  __exports__["default"] = hasMany;
9347
9657
  });
9348
9658
  define("ember-data/system/relationships/relationship",
9349
- ["ember-data/system/promise_proxies","exports"],
9350
- function(__dependency1__, __exports__) {
9659
+ ["ember-data/system/promise_proxies","ember-data/system/map","exports"],
9660
+ function(__dependency1__, __dependency2__, __exports__) {
9351
9661
  "use strict";
9352
- var PromiseArray = __dependency1__.PromiseArray;
9662
+ var PromiseManyArray = __dependency1__.PromiseManyArray;
9353
9663
  var PromiseObject = __dependency1__.PromiseObject;
9664
+ var OrderedSet = __dependency2__.OrderedSet;
9354
9665
 
9355
9666
  var Relationship = function(store, record, inverseKey, relationshipMeta) {
9356
- this.members = new Ember.OrderedSet();
9667
+ this.members = new OrderedSet();
9357
9668
  this.store = store;
9358
9669
  this.key = relationshipMeta.key;
9359
9670
  this.inverseKey = inverseKey;
@@ -9361,11 +9672,15 @@ define("ember-data/system/relationships/relationship",
9361
9672
  this.key = relationshipMeta.key;
9362
9673
  this.isAsync = relationshipMeta.options.async;
9363
9674
  this.relationshipMeta = relationshipMeta;
9675
+ //This probably breaks for polymorphic relationship in complex scenarios, due to
9676
+ //multiple possible typeKeys
9677
+ this.inverseKeyForImplicit = this.store.modelFor(this.record.constructor).typeKey + this.key;
9678
+ //Cached promise when fetching the relationship from a link
9679
+ this.linkPromise = null;
9364
9680
  };
9365
9681
 
9366
9682
  Relationship.prototype = {
9367
9683
  constructor: Relationship,
9368
- hasFetchedLink: false,
9369
9684
 
9370
9685
  destroy: Ember.K,
9371
9686
 
@@ -9375,6 +9690,18 @@ define("ember-data/system/relationships/relationship",
9375
9690
  }, this);
9376
9691
  },
9377
9692
 
9693
+ disconnect: function(){
9694
+ this.members.forEach(function(member) {
9695
+ this.removeRecordFromInverse(member);
9696
+ }, this);
9697
+ },
9698
+
9699
+ reconnect: function(){
9700
+ this.members.forEach(function(member) {
9701
+ this.addRecordToInverse(member);
9702
+ }, this);
9703
+ },
9704
+
9378
9705
  removeRecords: function(records){
9379
9706
  var that = this;
9380
9707
  records.forEach(function(record){
@@ -9392,13 +9719,17 @@ define("ember-data/system/relationships/relationship",
9392
9719
  });
9393
9720
  },
9394
9721
 
9395
-
9396
9722
  addRecord: function(record, idx) {
9397
9723
  if (!this.members.has(record)) {
9398
9724
  this.members.add(record);
9399
9725
  this.notifyRecordRelationshipAdded(record, idx);
9400
9726
  if (this.inverseKey) {
9401
9727
  record._relationships[this.inverseKey].addRecord(this.record);
9728
+ } else {
9729
+ if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
9730
+ record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, {options:{}});
9731
+ }
9732
+ record._implicitRelationships[this.inverseKeyForImplicit].addRecord(this.record);
9402
9733
  }
9403
9734
  this.record.updateRecordArrays();
9404
9735
  }
@@ -9406,31 +9737,64 @@ define("ember-data/system/relationships/relationship",
9406
9737
 
9407
9738
  removeRecord: function(record) {
9408
9739
  if (this.members.has(record)) {
9409
- this.members.remove(record);
9410
- this.notifyRecordRelationshipRemoved(record);
9740
+ this.removeRecordFromOwn(record);
9411
9741
  if (this.inverseKey) {
9412
- var inverseRelationship = record._relationships[this.inverseKey];
9413
- //Need to check for existence, as the record might unloading at the moment
9414
- if (inverseRelationship) {
9415
- inverseRelationship.removeRecord(this.record);
9742
+ this.removeRecordFromInverse(record);
9743
+ } else {
9744
+ if (record._implicitRelationships[this.inverseKeyForImplicit]) {
9745
+ record._implicitRelationships[this.inverseKeyForImplicit].removeRecord(this.record);
9416
9746
  }
9417
9747
  }
9418
- this.record.updateRecordArrays();
9419
9748
  }
9420
9749
  },
9421
9750
 
9751
+ addRecordToInverse: function(record) {
9752
+ if (this.inverseKey) {
9753
+ record._relationships[this.inverseKey].addRecord(this.record);
9754
+ }
9755
+ },
9756
+
9757
+ removeRecordFromInverse: function(record) {
9758
+ var inverseRelationship = record._relationships[this.inverseKey];
9759
+ //Need to check for existence, as the record might unloading at the moment
9760
+ if (inverseRelationship) {
9761
+ inverseRelationship.removeRecordFromOwn(this.record);
9762
+ }
9763
+ },
9764
+
9765
+ removeRecordFromOwn: function(record) {
9766
+ this.members["delete"](record);
9767
+ this.notifyRecordRelationshipRemoved(record);
9768
+ this.record.updateRecordArrays();
9769
+ },
9770
+
9422
9771
  updateLink: function(link) {
9423
9772
  if (link !== this.link) {
9424
9773
  this.link = link;
9425
- this.hasFetchedLink = false;
9774
+ this.linkPromise = null;
9426
9775
  this.record.notifyPropertyChange(this.key);
9427
9776
  }
9428
9777
  },
9429
9778
 
9779
+ findLink: function() {
9780
+ if (this.linkPromise) {
9781
+ return this.linkPromise;
9782
+ } else {
9783
+ var promise = this.fetchLink();
9784
+ this.linkPromise = promise;
9785
+ return promise.then(function(result) {
9786
+ return result;
9787
+ });
9788
+ }
9789
+ },
9790
+
9430
9791
  updateRecordsFromAdapter: function(records) {
9431
9792
  //TODO Once we have adapter support, we need to handle updated and canonical changes
9432
9793
  this.computeChanges(records);
9433
- }
9794
+ },
9795
+
9796
+ notifyRecordRelationshipAdded: Ember.K,
9797
+ notifyRecordRelationshipRemoved: Ember.K
9434
9798
  };
9435
9799
 
9436
9800
  var ManyRelationship = function(store, record, inverseKey, relationshipMeta) {
@@ -9459,49 +9823,84 @@ define("ember-data/system/relationships/relationship",
9459
9823
  this.record.notifyHasManyRemoved(this.key, record);
9460
9824
  };
9461
9825
 
9826
+ ManyRelationship.prototype.reload = function() {
9827
+ var self = this;
9828
+ if (this.link) {
9829
+ return this.fetchLink();
9830
+ } else {
9831
+ return this.store.scheduleFetchMany(this.manyArray.toArray()).then(function() {
9832
+ //Goes away after the manyArray refactor
9833
+ self.manyArray.set('isLoaded', true);
9834
+ return self.manyArray;
9835
+ });
9836
+ }
9837
+ };
9838
+
9462
9839
  ManyRelationship.prototype.computeChanges = function(records) {
9463
9840
  var members = this.members;
9841
+ var recordsToRemove = [];
9842
+ var length;
9843
+ var record;
9844
+ var i;
9464
9845
 
9465
9846
  records = setForArray(records);
9466
9847
 
9467
9848
  members.forEach(function(member) {
9468
9849
  if (records.has(member)) return;
9469
9850
 
9470
- this.removeRecord(member);
9471
- }, this);
9851
+ recordsToRemove.push(member);
9852
+ });
9853
+ this.removeRecords(recordsToRemove);
9472
9854
 
9473
9855
  var hasManyArray = this.manyArray;
9474
9856
 
9475
- records.forEach(function(record, index) {
9857
+ // Using records.toArray() since currently using
9858
+ // removeRecord can modify length, messing stuff up
9859
+ // forEach since it directly looks at "length" each
9860
+ // iteration
9861
+ records = records.toArray();
9862
+ length = records.length;
9863
+ for (i = 0; i < length; i++){
9864
+ record = records[i];
9476
9865
  //Need to preserve the order of incoming records
9477
- if (hasManyArray.objectAt(index) === record ) return;
9478
-
9866
+ if (hasManyArray.objectAt(i) === record ) {
9867
+ continue;
9868
+ }
9479
9869
  this.removeRecord(record);
9480
- this.addRecord(record, index);
9481
- }, this);
9870
+ this.addRecord(record, i);
9871
+ }
9482
9872
  };
9483
9873
 
9874
+ ManyRelationship.prototype.fetchLink = function() {
9875
+ var self = this;
9876
+ return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records){
9877
+ self.updateRecordsFromAdapter(records);
9878
+ return self.manyArray;
9879
+ });
9880
+ };
9881
+
9882
+ ManyRelationship.prototype.findRecords = function() {
9883
+ var manyArray = this.manyArray;
9884
+ return this.store.findMany(manyArray.toArray()).then(function(){
9885
+ //Goes away after the manyArray refactor
9886
+ manyArray.set('isLoaded', true);
9887
+ return manyArray;
9888
+ });
9889
+ };
9484
9890
 
9485
9891
  ManyRelationship.prototype.getRecords = function() {
9486
9892
  if (this.isAsync) {
9487
9893
  var self = this;
9488
9894
  var promise;
9489
- if (this.link && !this.hasFetchedLink) {
9490
- promise = this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records){
9491
- self.updateRecordsFromAdapter(records);
9492
- self.hasFetchedLink = true;
9493
- //TODO(Igor) try to abstract the isLoaded part
9494
- self.manyArray.set('isLoaded', true);
9495
- return self.manyArray;
9895
+ if (this.link) {
9896
+ promise = this.findLink().then(function() {
9897
+ return self.findRecords();
9496
9898
  });
9497
9899
  } else {
9498
- var manyArray = this.manyArray;
9499
- promise = this.store.findMany(manyArray.toArray()).then(function(){
9500
- self.manyArray.set('isLoaded', true);
9501
- return manyArray;
9502
- });
9900
+ promise = this.findRecords();
9503
9901
  }
9504
- return PromiseArray.create({
9902
+ return PromiseManyArray.create({
9903
+ content: this.manyArray,
9505
9904
  promise: promise
9506
9905
  });
9507
9906
  } else {
@@ -9514,10 +9913,8 @@ define("ember-data/system/relationships/relationship",
9514
9913
 
9515
9914
  var BelongsToRelationship = function(store, record, inverseKey, relationshipMeta) {
9516
9915
  this._super$constructor(store, record, inverseKey, relationshipMeta);
9517
- this.members.add(record);
9518
9916
  this.record = record;
9519
9917
  this.key = relationshipMeta.key;
9520
- this.inverseKey = inverseKey;
9521
9918
  this.inverseRecord = null;
9522
9919
  };
9523
9920
 
@@ -9539,7 +9936,7 @@ define("ember-data/system/relationships/relationship",
9539
9936
  var type = this.relationshipMeta.type;
9540
9937
  Ember.assert("You can only add a '" + type.typeKey + "' record to this relationship", newRecord instanceof type);
9541
9938
 
9542
- if (this.inverseRecord && this.inverseKey) {
9939
+ if (this.inverseRecord) {
9543
9940
  this.removeRecord(this.inverseRecord);
9544
9941
  }
9545
9942
 
@@ -9547,6 +9944,12 @@ define("ember-data/system/relationships/relationship",
9547
9944
  this._super$addRecord(newRecord);
9548
9945
  };
9549
9946
 
9947
+ BelongsToRelationship.prototype.setRecordPromise = function(newPromise) {
9948
+ var content = newPromise.get && newPromise.get('content');
9949
+ Ember.assert("You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.", content !== undefined);
9950
+ this.setRecord(content);
9951
+ };
9952
+
9550
9953
  BelongsToRelationship.prototype.notifyRecordRelationshipAdded = function(newRecord) {
9551
9954
  this.record.notifyBelongsToAdded(this.key, this);
9552
9955
  };
@@ -9555,36 +9958,44 @@ define("ember-data/system/relationships/relationship",
9555
9958
  this.record.notifyBelongsToRemoved(this.key, this);
9556
9959
  };
9557
9960
 
9558
- BelongsToRelationship.prototype._super$removeRecord = Relationship.prototype.removeRecord;
9559
- BelongsToRelationship.prototype.removeRecord = function(record) {
9961
+ BelongsToRelationship.prototype._super$removeRecordFromOwn = Relationship.prototype.removeRecordFromOwn;
9962
+ BelongsToRelationship.prototype.removeRecordFromOwn = function(record) {
9560
9963
  if (!this.members.has(record)){ return;}
9561
- this._super$removeRecord(record);
9964
+ this._super$removeRecordFromOwn(record);
9562
9965
  this.inverseRecord = null;
9563
9966
  };
9564
9967
 
9565
- BelongsToRelationship.prototype.currentOtherSideFor = function() {
9566
- return this.inverseRecord;
9968
+ BelongsToRelationship.prototype.findRecord = function() {
9969
+ if (this.inverseRecord) {
9970
+ return this.store._findByRecord(this.inverseRecord);
9971
+ } else {
9972
+ return Ember.RSVP.Promise.resolve(null);
9973
+ }
9974
+ };
9975
+
9976
+ BelongsToRelationship.prototype.fetchLink = function() {
9977
+ var self = this;
9978
+ return this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record){
9979
+ self.addRecord(record);
9980
+ return record;
9981
+ });
9567
9982
  };
9568
9983
 
9569
9984
  BelongsToRelationship.prototype.getRecord = function() {
9570
9985
  if (this.isAsync) {
9571
9986
  var promise;
9572
-
9573
- if (this.link && !this.hasFetchedLink){
9987
+ if (this.link){
9574
9988
  var self = this;
9575
- promise = this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record){
9576
- self.addRecord(record);
9577
- self.hasFetchedLink = true;
9578
- return record;
9989
+ promise = this.findLink().then(function() {
9990
+ return self.findRecord();
9579
9991
  });
9580
- } else if (this.inverseRecord) {
9581
- promise = this.store._findByRecord(this.inverseRecord);
9582
9992
  } else {
9583
- promise = Ember.RSVP.Promise.resolve(null);
9993
+ promise = this.findRecord();
9584
9994
  }
9585
9995
 
9586
9996
  return PromiseObject.create({
9587
- promise: promise
9997
+ promise: promise,
9998
+ content: this.inverseRecord
9588
9999
  });
9589
10000
  } else {
9590
10001
  Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.belongsTo({ async: true })`)", this.inverseRecord === null || !this.inverseRecord.get('isEmpty'));
@@ -9593,7 +10004,7 @@ define("ember-data/system/relationships/relationship",
9593
10004
  };
9594
10005
 
9595
10006
  function setForArray(array) {
9596
- var set = new Ember.OrderedSet();
10007
+ var set = new OrderedSet();
9597
10008
 
9598
10009
  if (array) {
9599
10010
  for (var i=0, l=array.length; i<l; i++) {
@@ -9627,8 +10038,8 @@ define("ember-data/system/relationships/relationship",
9627
10038
  __exports__.createRelationshipFor = createRelationshipFor;
9628
10039
  });
9629
10040
  define("ember-data/system/store",
9630
- ["ember-data/system/adapter","ember-inflector/system/string","ember-data/system/promise_proxies","exports"],
9631
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
10041
+ ["ember-data/system/adapter","ember-inflector/system/string","ember-data/system/map","ember-data/system/promise_proxies","exports"],
10042
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
9632
10043
  "use strict";
9633
10044
  /*globals Ember*/
9634
10045
  /*jshint eqnull:true*/
@@ -9640,9 +10051,10 @@ define("ember-data/system/store",
9640
10051
  var InvalidError = __dependency1__.InvalidError;
9641
10052
  var Adapter = __dependency1__.Adapter;
9642
10053
  var singularize = __dependency2__.singularize;
10054
+ var Map = __dependency3__.Map;
9643
10055
 
9644
- var promiseArray = __dependency3__.promiseArray;
9645
- var promiseObject = __dependency3__.promiseObject;
10056
+ var promiseArray = __dependency4__.promiseArray;
10057
+ var promiseObject = __dependency4__.promiseObject;
9646
10058
 
9647
10059
 
9648
10060
  var get = Ember.get;
@@ -9777,7 +10189,7 @@ define("ember-data/system/store",
9777
10189
  });
9778
10190
  this._pendingSave = [];
9779
10191
  //Used to keep track of all the find requests that need to be coalesced
9780
- this._pendingFetch = Ember.Map.create();
10192
+ this._pendingFetch = Map.create();
9781
10193
  },
9782
10194
 
9783
10195
  /**
@@ -10165,10 +10577,10 @@ define("ember-data/system/store",
10165
10577
  }
10166
10578
 
10167
10579
  this._pendingFetch.forEach(this._flushPendingFetchForType, this);
10168
- this._pendingFetch = Ember.Map.create();
10580
+ this._pendingFetch = Map.create();
10169
10581
  },
10170
10582
 
10171
- _flushPendingFetchForType: function (type, recordResolverPairs) {
10583
+ _flushPendingFetchForType: function (recordResolverPairs, type) {
10172
10584
  var store = this;
10173
10585
  var adapter = store.adapterFor(type);
10174
10586
  var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
@@ -10772,7 +11184,7 @@ define("ember-data/system/store",
10772
11184
 
10773
11185
  @method typeMapFor
10774
11186
  @private
10775
- @param type
11187
+ @param {subclass of DS.Model} type
10776
11188
  @return {Object} typeMap
10777
11189
  */
10778
11190
  typeMapFor: function(type) {
@@ -10833,7 +11245,7 @@ define("ember-data/system/store",
10833
11245
  var factory;
10834
11246
 
10835
11247
  if (typeof key === 'string') {
10836
- factory = this.container.lookupFactory('model:' + key);
11248
+ factory = this.modelFactoryFor(key);
10837
11249
  if (!factory) {
10838
11250
  throw new Ember.Error("No model was found for '" + key + "'");
10839
11251
  }
@@ -10850,6 +11262,10 @@ define("ember-data/system/store",
10850
11262
  return factory;
10851
11263
  },
10852
11264
 
11265
+ modelFactoryFor: function(key){
11266
+ return this.container.lookupFactory('model:' + key);
11267
+ },
11268
+
10853
11269
  /**
10854
11270
  Push some data for a given type into the store.
10855
11271
 
@@ -11014,7 +11430,7 @@ define("ember-data/system/store",
11014
11430
  ```
11015
11431
 
11016
11432
  @method normalize
11017
- @param {String} The name of the model type for this payload
11433
+ @param {String} type The name of the model type for this payload
11018
11434
  @param {Object} payload
11019
11435
  @return {Object} The normalized payload
11020
11436
  */
@@ -11593,8 +12009,8 @@ define("ember-data/transforms/base",
11593
12009
  ```
11594
12010
 
11595
12011
  @method serialize
11596
- @param deserialized The deserialized value
11597
- @return The serialized value
12012
+ @param {mixed} deserialized The deserialized value
12013
+ @return {mixed} The serialized value
11598
12014
  */
11599
12015
  serialize: Ember.required(),
11600
12016
 
@@ -11611,8 +12027,8 @@ define("ember-data/transforms/base",
11611
12027
  ```
11612
12028
 
11613
12029
  @method deserialize
11614
- @param serialized The serialized value
11615
- @return The deserialized value
12030
+ @param {mixed} serialized The serialized value
12031
+ @return {mixed} The deserialized value
11616
12032
  */
11617
12033
  deserialize: Ember.required()
11618
12034
  });