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

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,26 +2,10 @@
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
-
15
5
  var registry = {}, seen = {}, state = {};
16
6
  var FAILED = false;
17
7
 
18
8
  define = function(name, deps, callback) {
19
-
20
- if (!_isArray(deps)) {
21
- callback = deps;
22
- deps = [];
23
- }
24
-
25
9
  registry[name] = {
26
10
  deps: deps,
27
11
  callback: callback
@@ -150,13 +134,12 @@ define("activemodel-adapter/system",
150
134
  __exports__.ActiveModelSerializer = ActiveModelSerializer;
151
135
  });
152
136
  define("activemodel-adapter/system/active_model_adapter",
153
- ["ember-data/adapters","ember-data/system/adapter","ember-inflector","activemodel-adapter/system/active_model_serializer","exports"],
154
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
137
+ ["ember-data/adapters","ember-data/system/adapter","ember-inflector","exports"],
138
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
155
139
  "use strict";
156
140
  var RESTAdapter = __dependency1__.RESTAdapter;
157
141
  var InvalidError = __dependency2__.InvalidError;
158
142
  var pluralize = __dependency3__.pluralize;
159
- var ActiveModelSerializer = __dependency4__["default"];
160
143
 
161
144
  /**
162
145
  @module ember-data
@@ -615,8 +598,8 @@ define("activemodel-adapter/system/active_model_serializer",
615
598
  __exports__["default"] = ActiveModelSerializer;
616
599
  });
617
600
  define("ember-data",
618
- ["ember-data/core","ember-data/ext/date","ember-data/system/store","ember-data/system/model","ember-data/system/changes","ember-data/system/adapter","ember-data/system/debug","ember-data/system/record_arrays","ember-data/system/record_array_manager","ember-data/adapters","ember-data/serializers/json_serializer","ember-data/serializers/rest_serializer","ember-inflector","ember-data/serializers/embedded_records_mixin","activemodel-adapter","ember-data/transforms","ember-data/system/relationships","ember-data/ember-initializer","ember-data/setup-container","ember-data/system/container_proxy","exports"],
619
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __exports__) {
601
+ ["ember-data/core","ember-data/ext/date","ember-data/system/promise_proxies","ember-data/system/store","ember-data/system/model","ember-data/system/adapter","ember-data/system/debug","ember-data/system/record_arrays","ember-data/system/record_array_manager","ember-data/adapters","ember-data/serializers/json_serializer","ember-data/serializers/rest_serializer","ember-inflector","ember-data/serializers/embedded_records_mixin","activemodel-adapter","ember-data/transforms","ember-data/system/relationships","ember-data/ember-initializer","ember-data/setup-container","ember-data/system/container_proxy","ember-data/system/relationships/relationship","exports"],
602
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __exports__) {
620
603
  "use strict";
621
604
  /**
622
605
  Ember Data
@@ -630,21 +613,13 @@ define("ember-data",
630
613
 
631
614
  var DS = __dependency1__["default"];
632
615
 
633
- var Store = __dependency3__.Store;
634
616
  var PromiseArray = __dependency3__.PromiseArray;
635
617
  var PromiseObject = __dependency3__.PromiseObject;
636
- var Model = __dependency4__.Model;
637
- var Errors = __dependency4__.Errors;
638
- var RootState = __dependency4__.RootState;
639
- var attr = __dependency4__.attr;
640
- var AttributeChange = __dependency5__.AttributeChange;
641
- var RelationshipChange = __dependency5__.RelationshipChange;
642
- var RelationshipChangeAdd = __dependency5__.RelationshipChangeAdd;
643
- var RelationshipChangeRemove = __dependency5__.RelationshipChangeRemove;
644
- var OneToManyChange = __dependency5__.OneToManyChange;
645
- var ManyToNoneChange = __dependency5__.ManyToNoneChange;
646
- var OneToOneChange = __dependency5__.OneToOneChange;
647
- var ManyToManyChange = __dependency5__.ManyToManyChange;
618
+ var Store = __dependency4__.Store;
619
+ var Model = __dependency5__.Model;
620
+ var Errors = __dependency5__.Errors;
621
+ var RootState = __dependency5__.RootState;
622
+ var attr = __dependency5__.attr;
648
623
  var InvalidError = __dependency6__.InvalidError;
649
624
  var Adapter = __dependency6__.Adapter;
650
625
  var DebugAdapter = __dependency7__["default"];
@@ -672,6 +647,7 @@ define("ember-data",
672
647
  var setupContainer = __dependency19__["default"];
673
648
 
674
649
  var ContainerProxy = __dependency20__["default"];
650
+ var Relationship = __dependency21__.Relationship;
675
651
 
676
652
  DS.Store = Store;
677
653
  DS.PromiseArray = PromiseArray;
@@ -682,14 +658,6 @@ define("ember-data",
682
658
  DS.attr = attr;
683
659
  DS.Errors = Errors;
684
660
 
685
- DS.AttributeChange = AttributeChange;
686
- DS.RelationshipChange = RelationshipChange;
687
- DS.RelationshipChangeAdd = RelationshipChangeAdd;
688
- DS.OneToManyChange = OneToManyChange;
689
- DS.ManyToNoneChange = OneToManyChange;
690
- DS.OneToOneChange = OneToOneChange;
691
- DS.ManyToManyChange = ManyToManyChange;
692
-
693
661
  DS.Adapter = Adapter;
694
662
  DS.InvalidError = InvalidError;
695
663
 
@@ -721,6 +689,8 @@ define("ember-data",
721
689
  DS.belongsTo = belongsTo;
722
690
  DS.hasMany = hasMany;
723
691
 
692
+ DS.Relationship = Relationship;
693
+
724
694
  DS.ContainerProxy = ContainerProxy;
725
695
 
726
696
  DS._setupContainer = setupContainer;
@@ -1067,15 +1037,16 @@ define("ember-data/adapters/fixture_adapter",
1067
1037
  var adapter = this;
1068
1038
 
1069
1039
  return new Ember.RSVP.Promise(function(resolve) {
1040
+ var value = Ember.copy(callback.call(context), true);
1070
1041
  if (get(adapter, 'simulateRemoteResponse')) {
1071
1042
  // Schedule with setTimeout
1072
1043
  Ember.run.later(function() {
1073
- resolve(callback.call(context));
1044
+ resolve(value);
1074
1045
  }, get(adapter, 'latency'));
1075
1046
  } else {
1076
1047
  // Asynchronous, but at the of the runloop with zero latency
1077
1048
  Ember.run.schedule('actions', null, function() {
1078
- resolve(callback.call(context));
1049
+ resolve(value);
1079
1050
  });
1080
1051
  }
1081
1052
  }, "DS: FixtureAdapter#simulateRemoteCall");
@@ -1090,7 +1061,8 @@ define("ember-data/adapters/rest_adapter",
1090
1061
  @module ember-data
1091
1062
  */
1092
1063
 
1093
- var Adapter = __dependency1__["default"];
1064
+ var Adapter = __dependency1__.Adapter;
1065
+ var InvalidError = __dependency1__.InvalidError;
1094
1066
  var get = Ember.get;
1095
1067
  var forEach = Ember.ArrayPolyfills.forEach;
1096
1068
 
@@ -1477,7 +1449,7 @@ define("ember-data/adapters/rest_adapter",
1477
1449
  @param {String} url
1478
1450
  @return {Promise} promise
1479
1451
  */
1480
- findHasMany: function(store, record, url) {
1452
+ findHasMany: function(store, record, url, relationship) {
1481
1453
  var host = get(this, 'host');
1482
1454
  var id = get(record, 'id');
1483
1455
  var type = record.constructor.typeKey;
@@ -1516,7 +1488,7 @@ define("ember-data/adapters/rest_adapter",
1516
1488
  @param {String} url
1517
1489
  @return {Promise} promise
1518
1490
  */
1519
- findBelongsTo: function(store, record, url) {
1491
+ findBelongsTo: function(store, record, url, relationship) {
1520
1492
  var id = get(record, 'id');
1521
1493
  var type = record.constructor.typeKey;
1522
1494
 
@@ -1807,9 +1779,10 @@ define("ember-data/adapters/rest_adapter",
1807
1779
 
1808
1780
  @method ajaxError
1809
1781
  @param {Object} jqXHR
1782
+ @param {Object} responseText
1810
1783
  @return {Object} jqXHR
1811
1784
  */
1812
- ajaxError: function(jqXHR) {
1785
+ ajaxError: function(jqXHR, responseText) {
1813
1786
  if (jqXHR && typeof jqXHR === 'object') {
1814
1787
  jqXHR.then = null;
1815
1788
  }
@@ -1817,6 +1790,32 @@ define("ember-data/adapters/rest_adapter",
1817
1790
  return jqXHR;
1818
1791
  },
1819
1792
 
1793
+ /**
1794
+ Takes an ajax response, and returns the json payload.
1795
+
1796
+ By default this hook just returns the jsonPayload passed to it.
1797
+ You might want to override it in two cases:
1798
+
1799
+ 1. Your API might return useful results in the request headers.
1800
+ If you need to access these, you can override this hook to copy them
1801
+ from jqXHR to the payload object so they can be processed in you serializer.
1802
+
1803
+
1804
+ 2. Your API might return errors as successful responses with status code
1805
+ 200 and an Errors text or object. You can return a DS.InvalidError from
1806
+ this hook and it will automatically reject the promise and put your record
1807
+ into the invald state.
1808
+
1809
+ @method ajaxError
1810
+ @param {Object} jqXHR
1811
+ @param {Object} jsonPayload
1812
+ @return {Object} jqXHR
1813
+ */
1814
+
1815
+ ajaxSuccess: function(jqXHR, jsonPayload) {
1816
+ return jsonPayload;
1817
+ },
1818
+
1820
1819
  /**
1821
1820
  Takes a URL, an HTTP method and a hash of data, and makes an
1822
1821
  HTTP request.
@@ -1847,12 +1846,17 @@ define("ember-data/adapters/rest_adapter",
1847
1846
  return new Ember.RSVP.Promise(function(resolve, reject) {
1848
1847
  var hash = adapter.ajaxOptions(url, type, options);
1849
1848
 
1850
- hash.success = function(json) {
1851
- Ember.run(null, resolve, json);
1849
+ hash.success = function(json, textStatus, jqXHR) {
1850
+ json = adapter.ajaxSuccess(jqXHR, json);
1851
+ if (json instanceof InvalidError) {
1852
+ Ember.run(null, reject, json);
1853
+ } else {
1854
+ Ember.run(null, resolve, json);
1855
+ }
1852
1856
  };
1853
1857
 
1854
1858
  hash.error = function(jqXHR, textStatus, errorThrown) {
1855
- Ember.run(null, reject, adapter.ajaxError(jqXHR));
1859
+ Ember.run(null, reject, adapter.ajaxError(jqXHR, jqXHR.responseText));
1856
1860
  };
1857
1861
 
1858
1862
  Ember.$.ajax(hash);
@@ -1920,11 +1924,11 @@ define("ember-data/core",
1920
1924
  /**
1921
1925
  @property VERSION
1922
1926
  @type String
1923
- @default '1.0.0-beta.9'
1927
+ @default '1.0.0-beta.10'
1924
1928
  @static
1925
1929
  */
1926
1930
  DS = Ember.Namespace.create({
1927
- VERSION: '1.0.0-beta.9'
1931
+ VERSION: '1.0.0-beta.10'
1928
1932
  });
1929
1933
 
1930
1934
  if (Ember.libraries) {
@@ -2193,15 +2197,13 @@ define("ember-data/serializers",
2193
2197
  __exports__.RESTSerializer = RESTSerializer;
2194
2198
  });
2195
2199
  define("ember-data/serializers/embedded_records_mixin",
2196
- ["ember-inflector","exports"],
2197
- function(__dependency1__, __exports__) {
2200
+ ["exports"],
2201
+ function(__exports__) {
2198
2202
  "use strict";
2199
2203
  var get = Ember.get;
2200
2204
  var forEach = Ember.EnumerableUtils.forEach;
2201
2205
  var camelize = Ember.String.camelize;
2202
2206
 
2203
- var pluralize = __dependency1__.pluralize;
2204
-
2205
2207
  /**
2206
2208
  ## Using Embedded Records
2207
2209
 
@@ -2220,6 +2222,11 @@ define("ember-data/serializers/embedded_records_mixin",
2220
2222
  }
2221
2223
  })
2222
2224
  ```
2225
+ Note that this use of `{embedded: 'always'}` is unrelated to
2226
+ the `{embedded: 'always'}` that is defined as an option on `DS.attr` as part of
2227
+ defining a model while working with the ActiveModelSerializer. Nevertheless,
2228
+ using `{embedded: 'always'}` as an option to DS.attr is not a valid way to setup
2229
+ embedded records.
2223
2230
 
2224
2231
  The `attrs` option for a resource `{embedded: 'always'}` is shorthand for:
2225
2232
 
@@ -2253,7 +2260,11 @@ define("ember-data/serializers/embedded_records_mixin",
2253
2260
 
2254
2261
  ### Model Relationships
2255
2262
 
2256
- Embedded records must have a model defined to be extracted and serialized.
2263
+ Embedded records must have a model defined to be extracted and serialized. Note that
2264
+ when defining any relationships on your model such as `belongsTo` and `hasMany`, you
2265
+ should not both specify `async:true` and also indicate through the serializer's
2266
+ `attrs` attribute that the related model should be embedded. If a model is
2267
+ declared embedded, then do not use `async:true`.
2257
2268
 
2258
2269
  To successfully extract and serialize embedded records the model relationships
2259
2270
  must be setup correcty See the
@@ -2265,9 +2276,9 @@ define("ember-data/serializers/embedded_records_mixin",
2265
2276
 
2266
2277
  ### Example JSON payloads, Models and Serializers
2267
2278
 
2268
- **When customizing a serializer it is imporant to grok what the cusomizations
2269
- are, please read the docs for the methods this mixin provides, in case you need
2270
- to modify to fit your specific needs.**
2279
+ **When customizing a serializer it is important to grok what the customizations
2280
+ are. Please read the docs for the methods this mixin provides, in case you need
2281
+ to modify it to fit your specific needs.**
2271
2282
 
2272
2283
  For example review the docs for each method of this mixin:
2273
2284
  * [normalize](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_normalize)
@@ -2370,7 +2381,6 @@ define("ember-data/serializers/embedded_records_mixin",
2370
2381
  */
2371
2382
  serializeBelongsTo: function(record, json, relationship) {
2372
2383
  var attr = relationship.key;
2373
- var attrs = this.get('attrs');
2374
2384
  if (this.noSerializeOptionSpecified(attr)) {
2375
2385
  this._super(record, json, relationship);
2376
2386
  return;
@@ -2480,7 +2490,6 @@ define("ember-data/serializers/embedded_records_mixin",
2480
2490
  */
2481
2491
  serializeHasMany: function(record, json, relationship) {
2482
2492
  var attr = relationship.key;
2483
- var attrs = this.get('attrs');
2484
2493
  if (this.noSerializeOptionSpecified(attr)) {
2485
2494
  this._super(record, json, relationship);
2486
2495
  return;
@@ -2555,8 +2564,6 @@ define("ember-data/serializers/embedded_records_mixin",
2555
2564
  // checks config for attrs option to serialize records
2556
2565
  noSerializeOptionSpecified: function(attr) {
2557
2566
  var option = this.attrsOption(attr);
2558
- var serializeRecords = this.hasSerializeRecordsOption(attr);
2559
- var serializeIds = this.hasSerializeIdsOption(attr);
2560
2567
  return !(option && (option.serialize || option.embedded));
2561
2568
  },
2562
2569
 
@@ -2583,7 +2590,12 @@ define("ember-data/serializers/embedded_records_mixin",
2583
2590
  if (serializer.hasDeserializeRecordsOption(key)) {
2584
2591
  var embeddedType = store.modelFor(relationship.type.typeKey);
2585
2592
  if (relationship.kind === "hasMany") {
2586
- extractEmbeddedHasMany(store, key, embeddedType, partial);
2593
+ if (relationship.options.polymorphic) {
2594
+ extractEmbeddedHasManyPolymorphic(store, key, partial);
2595
+ }
2596
+ else {
2597
+ extractEmbeddedHasMany(store, key, embeddedType, partial);
2598
+ }
2587
2599
  }
2588
2600
  if (relationship.kind === "belongsTo") {
2589
2601
  extractEmbeddedBelongsTo(store, key, embeddedType, partial);
@@ -2613,6 +2625,28 @@ define("ember-data/serializers/embedded_records_mixin",
2613
2625
  return hash;
2614
2626
  }
2615
2627
 
2628
+ function extractEmbeddedHasManyPolymorphic(store, key, hash) {
2629
+ if (!hash[key]) {
2630
+ return hash;
2631
+ }
2632
+
2633
+ var ids = [];
2634
+
2635
+ forEach(hash[key], function(data) {
2636
+ var typeKey = data.type;
2637
+ var embeddedSerializer = store.serializerFor(typeKey);
2638
+ var embeddedType = store.modelFor(typeKey);
2639
+ var primaryKey = get(embeddedSerializer, 'primaryKey');
2640
+
2641
+ var embeddedRecord = embeddedSerializer.normalize(embeddedType, data, null);
2642
+ store.push(embeddedType, embeddedRecord);
2643
+ ids.push({ id: embeddedRecord[primaryKey], type: typeKey });
2644
+ });
2645
+
2646
+ hash[key] = ids;
2647
+ return hash;
2648
+ }
2649
+
2616
2650
  function extractEmbeddedBelongsTo(store, key, embeddedType, hash) {
2617
2651
  if (!hash[key]) {
2618
2652
  return hash;
@@ -2630,12 +2664,10 @@ define("ember-data/serializers/embedded_records_mixin",
2630
2664
  __exports__["default"] = EmbeddedRecordsMixin;
2631
2665
  });
2632
2666
  define("ember-data/serializers/json_serializer",
2633
- ["ember-data/system/changes","exports"],
2634
- function(__dependency1__, __exports__) {
2667
+ ["exports"],
2668
+ function(__exports__) {
2635
2669
  "use strict";
2636
- var RelationshipChange = __dependency1__.RelationshipChange;
2637
2670
  var get = Ember.get;
2638
- var set = Ember.set;
2639
2671
  var isNone = Ember.isNone;
2640
2672
  var map = Ember.ArrayPolyfills.map;
2641
2673
  var merge = Ember.merge;
@@ -2745,7 +2777,7 @@ define("ember-data/serializers/json_serializer",
2745
2777
  @return {Object} data The transformed data object
2746
2778
  */
2747
2779
  applyTransforms: function(type, data) {
2748
- type.eachTransformedAttribute(function(key, type) {
2780
+ type.eachTransformedAttribute(function applyTransform(key, type) {
2749
2781
  if (!data.hasOwnProperty(key)) { return; }
2750
2782
 
2751
2783
  var transform = this.transformFor(type);
@@ -2831,7 +2863,7 @@ define("ember-data/serializers/json_serializer",
2831
2863
  @private
2832
2864
  */
2833
2865
  normalizeAttributes: function(type, hash) {
2834
- var payloadKey, key;
2866
+ var payloadKey;
2835
2867
 
2836
2868
  if (this.keyForAttribute) {
2837
2869
  type.eachAttribute(function(key) {
@@ -2850,7 +2882,7 @@ define("ember-data/serializers/json_serializer",
2850
2882
  @private
2851
2883
  */
2852
2884
  normalizeRelationships: function(type, hash) {
2853
- var payloadKey, key;
2885
+ var payloadKey;
2854
2886
 
2855
2887
  if (this.keyForRelationship) {
2856
2888
  type.eachRelationship(function(key, relationship) {
@@ -3269,7 +3301,7 @@ define("ember-data/serializers/json_serializer",
3269
3301
  payloadKey = this.keyForRelationship(key, "hasMany");
3270
3302
  }
3271
3303
 
3272
- var relationshipType = RelationshipChange.determineRelationshipType(record.constructor, relationship);
3304
+ var relationshipType = record.constructor.determineRelationshipType(relationship);
3273
3305
 
3274
3306
  if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') {
3275
3307
  json[payloadKey] = get(record, key).mapBy('id');
@@ -3678,7 +3710,6 @@ define("ember-data/serializers/rest_serializer",
3678
3710
 
3679
3711
  var JSONSerializer = __dependency1__["default"];
3680
3712
  var get = Ember.get;
3681
- var set = Ember.set;
3682
3713
  var forEach = Ember.ArrayPolyfills.forEach;
3683
3714
  var map = Ember.ArrayPolyfills.map;
3684
3715
  var camelize = Ember.String.camelize;
@@ -4359,7 +4390,7 @@ define("ember-data/serializers/rest_serializer",
4359
4390
 
4360
4391
  /**
4361
4392
  You can use this method to customize the root keys serialized into the JSON.
4362
- By default the REST Serializer sends the typeKey of a model, whih is a camelized
4393
+ By default the REST Serializer sends the typeKey of a model, which is a camelized
4363
4394
  version of the name.
4364
4395
 
4365
4396
  For example, your server may expect underscored root objects.
@@ -4436,8 +4467,6 @@ define("ember-data/system/adapter",
4436
4467
  */
4437
4468
 
4438
4469
  var get = Ember.get;
4439
- var set = Ember.set;
4440
- var map = Ember.ArrayPolyfills.map;
4441
4470
 
4442
4471
  var errorProps = [
4443
4472
  'description',
@@ -4894,463 +4923,6 @@ define("ember-data/system/adapter",
4894
4923
  __exports__.Adapter = Adapter;
4895
4924
  __exports__["default"] = Adapter;
4896
4925
  });
4897
- define("ember-data/system/changes",
4898
- ["ember-data/system/changes/relationship_change","exports"],
4899
- function(__dependency1__, __exports__) {
4900
- "use strict";
4901
- /**
4902
- @module ember-data
4903
- */
4904
-
4905
- var RelationshipChange = __dependency1__.RelationshipChange;
4906
- var RelationshipChangeAdd = __dependency1__.RelationshipChangeAdd;
4907
- var RelationshipChangeRemove = __dependency1__.RelationshipChangeRemove;
4908
- var OneToManyChange = __dependency1__.OneToManyChange;
4909
- var ManyToNoneChange = __dependency1__.ManyToNoneChange;
4910
- var OneToOneChange = __dependency1__.OneToOneChange;
4911
- var ManyToManyChange = __dependency1__.ManyToManyChange;
4912
-
4913
- __exports__.RelationshipChange = RelationshipChange;
4914
- __exports__.RelationshipChangeAdd = RelationshipChangeAdd;
4915
- __exports__.RelationshipChangeRemove = RelationshipChangeRemove;
4916
- __exports__.OneToManyChange = OneToManyChange;
4917
- __exports__.ManyToNoneChange = ManyToNoneChange;
4918
- __exports__.OneToOneChange = OneToOneChange;
4919
- __exports__.ManyToManyChange = ManyToManyChange;
4920
- });
4921
- define("ember-data/system/changes/relationship_change",
4922
- ["ember-data/system/model/model","ember-data/system/relationship-meta","exports"],
4923
- function(__dependency1__, __dependency2__, __exports__) {
4924
- "use strict";
4925
- /**
4926
- @module ember-data
4927
- */
4928
-
4929
- var Model = __dependency1__["default"];
4930
- var isSyncRelationship = __dependency2__.isSyncRelationship;
4931
-
4932
- var get = Ember.get;
4933
- var set = Ember.set;
4934
- var forEach = Ember.EnumerableUtils.forEach;
4935
-
4936
- /**
4937
- @class RelationshipChange
4938
- @namespace DS
4939
- @private
4940
- @constructor
4941
- */
4942
- var RelationshipChange = function(options) {
4943
- this.parentRecord = options.parentRecord;
4944
- this.childRecord = options.childRecord;
4945
- this.firstRecord = options.firstRecord;
4946
- this.firstRecordKind = options.firstRecordKind;
4947
- this.firstRecordName = options.firstRecordName;
4948
- this.secondRecord = options.secondRecord;
4949
- this.secondRecordKind = options.secondRecordKind;
4950
- this.secondRecordName = options.secondRecordName;
4951
- this.changeType = options.changeType;
4952
- this.store = options.store;
4953
-
4954
- this.committed = {};
4955
- };
4956
-
4957
- /**
4958
- @class RelationshipChangeAdd
4959
- @namespace DS
4960
- @private
4961
- @constructor
4962
- */
4963
- function RelationshipChangeAdd(options){
4964
- RelationshipChange.call(this, options);
4965
- }
4966
-
4967
- /**
4968
- @class RelationshipChangeRemove
4969
- @namespace DS
4970
- @private
4971
- @constructor
4972
- */
4973
- function RelationshipChangeRemove(options){
4974
- RelationshipChange.call(this, options);
4975
- }
4976
-
4977
- RelationshipChange.create = function(options) {
4978
- return new RelationshipChange(options);
4979
- };
4980
-
4981
- RelationshipChangeAdd.create = function(options) {
4982
- return new RelationshipChangeAdd(options);
4983
- };
4984
-
4985
- RelationshipChangeRemove.create = function(options) {
4986
- return new RelationshipChangeRemove(options);
4987
- };
4988
-
4989
- var OneToManyChange = {};
4990
- var OneToNoneChange = {};
4991
- var ManyToNoneChange = {};
4992
- var OneToOneChange = {};
4993
- var ManyToManyChange = {};
4994
-
4995
- RelationshipChange._createChange = function(options){
4996
- if (options.changeType === 'add') {
4997
- return RelationshipChangeAdd.create(options);
4998
- }
4999
- if (options.changeType === 'remove') {
5000
- return RelationshipChangeRemove.create(options);
5001
- }
5002
- };
5003
-
5004
- RelationshipChange.determineRelationshipType = function(recordType, knownSide){
5005
- var knownKey = knownSide.key, key, otherKind;
5006
- var knownKind = knownSide.kind;
5007
-
5008
- var inverse = recordType.inverseFor(knownKey);
5009
-
5010
- if (inverse) {
5011
- key = inverse.name;
5012
- otherKind = inverse.kind;
5013
- }
5014
-
5015
- if (!inverse) {
5016
- return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
5017
- } else {
5018
- if (otherKind === 'belongsTo') {
5019
- return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
5020
- } else {
5021
- return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
5022
- }
5023
- }
5024
- };
5025
-
5026
- RelationshipChange.createChange = function(firstRecord, secondRecord, store, options){
5027
- // Get the type of the child based on the child's client ID
5028
- var firstRecordType = firstRecord.constructor, changeType;
5029
- changeType = RelationshipChange.determineRelationshipType(firstRecordType, options);
5030
- if (changeType === 'oneToMany') {
5031
- return OneToManyChange.createChange(firstRecord, secondRecord, store, options);
5032
- } else if (changeType === 'manyToOne') {
5033
- return OneToManyChange.createChange(secondRecord, firstRecord, store, options);
5034
- } else if (changeType === 'oneToNone') {
5035
- return OneToNoneChange.createChange(firstRecord, secondRecord, store, options);
5036
- } else if (changeType === 'manyToNone') {
5037
- return ManyToNoneChange.createChange(firstRecord, secondRecord, store, options);
5038
- } else if (changeType === 'oneToOne') {
5039
- return OneToOneChange.createChange(firstRecord, secondRecord, store, options);
5040
- } else if (changeType === 'manyToMany') {
5041
- return ManyToManyChange.createChange(firstRecord, secondRecord, store, options);
5042
- }
5043
- };
5044
-
5045
- OneToNoneChange.createChange = function(childRecord, parentRecord, store, options) {
5046
- var key = options.key;
5047
- var change = RelationshipChange._createChange({
5048
- parentRecord: parentRecord,
5049
- childRecord: childRecord,
5050
- firstRecord: childRecord,
5051
- store: store,
5052
- changeType: options.changeType,
5053
- firstRecordName: key,
5054
- firstRecordKind: 'belongsTo'
5055
- });
5056
-
5057
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5058
-
5059
- return change;
5060
- };
5061
-
5062
- ManyToNoneChange.createChange = function(childRecord, parentRecord, store, options) {
5063
- var key = options.key;
5064
- var change = RelationshipChange._createChange({
5065
- parentRecord: childRecord,
5066
- childRecord: parentRecord,
5067
- secondRecord: childRecord,
5068
- store: store,
5069
- changeType: options.changeType,
5070
- secondRecordName: options.key,
5071
- secondRecordKind: 'hasMany'
5072
- });
5073
-
5074
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5075
- return change;
5076
- };
5077
-
5078
-
5079
- ManyToManyChange.createChange = function(childRecord, parentRecord, store, options) {
5080
- // If the name of the belongsTo side of the relationship is specified,
5081
- // use that
5082
- // If the type of the parent is specified, look it up on the child's type
5083
- // definition.
5084
- var key = options.key;
5085
-
5086
- var change = RelationshipChange._createChange({
5087
- parentRecord: parentRecord,
5088
- childRecord: childRecord,
5089
- firstRecord: childRecord,
5090
- secondRecord: parentRecord,
5091
- firstRecordKind: 'hasMany',
5092
- secondRecordKind: 'hasMany',
5093
- store: store,
5094
- changeType: options.changeType,
5095
- firstRecordName: key
5096
- });
5097
-
5098
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5099
-
5100
- return change;
5101
- };
5102
-
5103
- OneToOneChange.createChange = function(childRecord, parentRecord, store, options) {
5104
- var key;
5105
-
5106
- // If the name of the belongsTo side of the relationship is specified,
5107
- // use that
5108
- // If the type of the parent is specified, look it up on the child's type
5109
- // definition.
5110
- if (options.parentType) {
5111
- key = options.parentType.inverseFor(options.key).name;
5112
- } else if (options.key) {
5113
- key = options.key;
5114
- } else {
5115
- }
5116
-
5117
- var change = RelationshipChange._createChange({
5118
- parentRecord: parentRecord,
5119
- childRecord: childRecord,
5120
- firstRecord: childRecord,
5121
- secondRecord: parentRecord,
5122
- firstRecordKind: 'belongsTo',
5123
- secondRecordKind: 'belongsTo',
5124
- store: store,
5125
- changeType: options.changeType,
5126
- firstRecordName: key
5127
- });
5128
-
5129
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5130
-
5131
- return change;
5132
- };
5133
-
5134
- OneToOneChange.maintainInvariant = function(options, store, childRecord, key){
5135
- if (options.changeType === 'add' && store.recordIsMaterialized(childRecord)) {
5136
- var oldParent = get(childRecord, key);
5137
- if (oldParent) {
5138
- var correspondingChange = OneToOneChange.createChange(childRecord, oldParent, store, {
5139
- parentType: options.parentType,
5140
- hasManyName: options.hasManyName,
5141
- changeType: 'remove',
5142
- key: options.key
5143
- });
5144
- store.addRelationshipChangeFor(childRecord, key, options.parentRecord , null, correspondingChange);
5145
- correspondingChange.sync();
5146
- }
5147
- }
5148
- };
5149
-
5150
- OneToManyChange.createChange = function(childRecord, parentRecord, store, options) {
5151
- var key;
5152
-
5153
- // If the name of the belongsTo side of the relationship is specified,
5154
- // use that
5155
- // If the type of the parent is specified, look it up on the child's type
5156
- // definition.
5157
- if (options.parentType) {
5158
- key = options.parentType.inverseFor(options.key).name;
5159
- OneToManyChange.maintainInvariant( options, store, childRecord, key );
5160
- } else if (options.key) {
5161
- key = options.key;
5162
- } else {
5163
- }
5164
-
5165
- var change = RelationshipChange._createChange({
5166
- parentRecord: parentRecord,
5167
- childRecord: childRecord,
5168
- firstRecord: childRecord,
5169
- secondRecord: parentRecord,
5170
- firstRecordKind: 'belongsTo',
5171
- secondRecordKind: 'hasMany',
5172
- store: store,
5173
- changeType: options.changeType,
5174
- firstRecordName: key
5175
- });
5176
-
5177
- store.addRelationshipChangeFor(childRecord, key, parentRecord, change.getSecondRecordName(), change);
5178
-
5179
- return change;
5180
- };
5181
-
5182
- OneToManyChange.maintainInvariant = function(options, store, childRecord, key){
5183
- if (options.changeType === 'add' && childRecord) {
5184
- var oldParent = get(childRecord, key);
5185
- if (oldParent) {
5186
- var correspondingChange = OneToManyChange.createChange(childRecord, oldParent, store, {
5187
- parentType: options.parentType,
5188
- hasManyName: options.hasManyName,
5189
- changeType: 'remove',
5190
- key: options.key
5191
- });
5192
- store.addRelationshipChangeFor(childRecord, key, options.parentRecord, correspondingChange.getSecondRecordName(), correspondingChange);
5193
- correspondingChange.sync();
5194
- }
5195
- }
5196
- };
5197
-
5198
- /**
5199
- @class RelationshipChange
5200
- @namespace DS
5201
- */
5202
- RelationshipChange.prototype = {
5203
- getSecondRecordName: function() {
5204
- var name = this.secondRecordName, parent;
5205
-
5206
- if (!name) {
5207
- parent = this.secondRecord;
5208
- if (!parent) { return; }
5209
-
5210
- var childType = this.firstRecord.constructor;
5211
- var inverse = childType.inverseFor(this.firstRecordName);
5212
- this.secondRecordName = inverse.name;
5213
- }
5214
-
5215
- return this.secondRecordName;
5216
- },
5217
-
5218
- /**
5219
- Get the name of the relationship on the belongsTo side.
5220
-
5221
- @method getFirstRecordName
5222
- @return {String}
5223
- */
5224
- getFirstRecordName: function() {
5225
- return this.firstRecordName;
5226
- },
5227
-
5228
- /**
5229
- @method destroy
5230
- @private
5231
- */
5232
- destroy: function() {
5233
- var childRecord = this.childRecord;
5234
- var belongsToName = this.getFirstRecordName();
5235
- var hasManyName = this.getSecondRecordName();
5236
- var store = this.store;
5237
-
5238
- store.removeRelationshipChangeFor(childRecord, belongsToName, this.parentRecord, hasManyName, this.changeType);
5239
- },
5240
-
5241
- getSecondRecord: function(){
5242
- return this.secondRecord;
5243
- },
5244
-
5245
- /**
5246
- @method getFirstRecord
5247
- @private
5248
- */
5249
- getFirstRecord: function() {
5250
- return this.firstRecord;
5251
- },
5252
-
5253
- coalesce: function(){
5254
- var relationshipPairs = this.store.relationshipChangePairsFor(this.firstRecord);
5255
- forEach(relationshipPairs, function(pair) {
5256
- var addedChange = pair['add'];
5257
- var removedChange = pair['remove'];
5258
- if (addedChange && removedChange) {
5259
- addedChange.destroy();
5260
- removedChange.destroy();
5261
- }
5262
- });
5263
- }
5264
- };
5265
-
5266
- RelationshipChangeAdd.prototype = Ember.create(RelationshipChange.create({}));
5267
- RelationshipChangeRemove.prototype = Ember.create(RelationshipChange.create({}));
5268
-
5269
- RelationshipChangeAdd.prototype.changeType = 'add';
5270
- RelationshipChangeAdd.prototype.sync = function() {
5271
- var secondRecordName = this.getSecondRecordName();
5272
- var firstRecordName = this.getFirstRecordName();
5273
- var firstRecord = this.getFirstRecord();
5274
- var secondRecord = this.getSecondRecord();
5275
-
5276
- //Ember.assert("You specified a hasMany (" + hasManyName + ") on " + (!belongsToName && (newParent || oldParent || this.lastParent).constructor) + " but did not specify an inverse belongsTo on " + child.constructor, belongsToName);
5277
- //Ember.assert("You specified a belongsTo (" + belongsToName + ") on " + child.constructor + " but did not specify an inverse hasMany on " + (!hasManyName && (newParent || oldParent || this.lastParentRecord).constructor), hasManyName);
5278
-
5279
- if (secondRecord instanceof Model && firstRecord instanceof Model) {
5280
- if (this.secondRecordKind === 'belongsTo') {
5281
- secondRecord.suspendRelationshipObservers(function() {
5282
- set(secondRecord, secondRecordName, firstRecord);
5283
- });
5284
- } else if (this.secondRecordKind === 'hasMany' && isSyncRelationship(secondRecord, secondRecordName)) {
5285
- secondRecord.suspendRelationshipObservers(function() {
5286
- var relationship = get(secondRecord, secondRecordName);
5287
- relationship.addObject(firstRecord);
5288
- });
5289
- }
5290
- }
5291
-
5292
- if (firstRecord instanceof Model && secondRecord instanceof Model && get(firstRecord, firstRecordName) !== secondRecord) {
5293
- if (this.firstRecordKind === 'belongsTo') {
5294
- firstRecord.suspendRelationshipObservers(function() {
5295
- set(firstRecord, firstRecordName, secondRecord);
5296
- });
5297
- } else if (this.firstRecordKind === 'hasMany' && isSyncRelationship(secondRecord, secondRecordName)) {
5298
- firstRecord.suspendRelationshipObservers(function() {
5299
- var relationship = get(firstRecord, firstRecordName);
5300
- relationship.addObject(secondRecord);
5301
- });
5302
- }
5303
- }
5304
- this.coalesce();
5305
- };
5306
-
5307
- RelationshipChangeRemove.prototype.changeType = 'remove';
5308
- RelationshipChangeRemove.prototype.sync = function() {
5309
- var secondRecordName = this.getSecondRecordName();
5310
- var firstRecordName = this.getFirstRecordName();
5311
- var firstRecord = this.getFirstRecord();
5312
- var secondRecord = this.getSecondRecord();
5313
-
5314
- //Ember.assert("You specified a hasMany (" + hasManyName + ") on " + (!belongsToName && (newParent || oldParent || this.lastParent).constructor) + " but did not specify an inverse belongsTo on " + child.constructor, belongsToName);
5315
- //Ember.assert("You specified a belongsTo (" + belongsToName + ") on " + child.constructor + " but did not specify an inverse hasMany on " + (!hasManyName && (newParent || oldParent || this.lastParentRecord).constructor), hasManyName);
5316
-
5317
- if (secondRecord instanceof Model && firstRecord instanceof Model) {
5318
- if (this.secondRecordKind === 'belongsTo') {
5319
- secondRecord.suspendRelationshipObservers(function() {
5320
- set(secondRecord, secondRecordName, null);
5321
- });
5322
- } else if (this.secondRecordKind === 'hasMany' && isSyncRelationship(secondRecord, secondRecordName)) {
5323
- secondRecord.suspendRelationshipObservers(function() {
5324
- var relationship = get(secondRecord, secondRecordName);
5325
- relationship.removeObject(firstRecord);
5326
- });
5327
- }
5328
- }
5329
-
5330
- if (firstRecord instanceof Model && get(firstRecord, firstRecordName)) {
5331
- if (this.firstRecordKind === 'belongsTo') {
5332
- firstRecord.suspendRelationshipObservers(function() {
5333
- set(firstRecord, firstRecordName, null);
5334
- });
5335
- } else if (this.firstRecordKind === 'hasMany' && isSyncRelationship(firstRecord, firstRecordName)) {
5336
- firstRecord.suspendRelationshipObservers(function() {
5337
- var relationship = get(firstRecord, firstRecordName);
5338
- relationship.removeObject(secondRecord);
5339
- });
5340
- }
5341
- }
5342
-
5343
- this.coalesce();
5344
- };
5345
-
5346
- __exports__.RelationshipChange = RelationshipChange;
5347
- __exports__.RelationshipChangeAdd = RelationshipChangeAdd;
5348
- __exports__.RelationshipChangeRemove = RelationshipChangeRemove;
5349
- __exports__.OneToManyChange = OneToManyChange;
5350
- __exports__.ManyToNoneChange = ManyToNoneChange;
5351
- __exports__.OneToOneChange = OneToOneChange;
5352
- __exports__.ManyToManyChange = ManyToManyChange;
5353
- });
5354
4926
  define("ember-data/system/container_proxy",
5355
4927
  ["exports"],
5356
4928
  function(__exports__) {
@@ -5391,7 +4963,7 @@ define("ember-data/system/container_proxy",
5391
4963
  };
5392
4964
 
5393
4965
  ContainerProxy.prototype.registerDeprecations = function(proxyPairs) {
5394
- var i, proxyPair, deprecated, valid, proxy;
4966
+ var i, proxyPair, deprecated, valid;
5395
4967
 
5396
4968
  for (i = proxyPairs.length; i > 0; i--) {
5397
4969
  proxyPair = proxyPairs[i - 1];
@@ -6285,12 +5857,14 @@ define("ember-data/system/model/errors",
6285
5857
  });
6286
5858
  });
6287
5859
  define("ember-data/system/model/model",
6288
- ["ember-data/system/model/states","ember-data/system/model/errors","ember-data/system/store","exports"],
6289
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
5860
+ ["ember-data/system/model/states","ember-data/system/model/errors","ember-data/system/promise_proxies","ember-data/system/relationships/relationship","exports"],
5861
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
6290
5862
  "use strict";
6291
5863
  var RootState = __dependency1__["default"];
6292
5864
  var Errors = __dependency2__["default"];
6293
5865
  var PromiseObject = __dependency3__.PromiseObject;
5866
+ var createRelationshipFor = __dependency4__.createRelationshipFor;
5867
+
6294
5868
  /**
6295
5869
  @module ember-data
6296
5870
  */
@@ -6300,6 +5874,7 @@ define("ember-data/system/model/model",
6300
5874
  var merge = Ember.merge;
6301
5875
  var Promise = Ember.RSVP.Promise;
6302
5876
  var forEach = Ember.ArrayPolyfills.forEach;
5877
+ var map = Ember.ArrayPolyfills.map;
6303
5878
 
6304
5879
  var JSONSerializer;
6305
5880
  var retrieveFromCurrentState = Ember.computed('currentState', function(key, value) {
@@ -6732,6 +6307,12 @@ define("ember-data/system/model/model",
6732
6307
  this._attributes = {};
6733
6308
  this._inFlightAttributes = {};
6734
6309
  this._relationships = {};
6310
+ var model = this;
6311
+ //TODO Move into a getter for better perf
6312
+ this.constructor.eachRelationship(function(key, descriptor) {
6313
+ model._relationships[key] = createRelationshipFor(model, descriptor, model.store);
6314
+ });
6315
+
6735
6316
  },
6736
6317
 
6737
6318
  /**
@@ -6914,13 +6495,11 @@ define("ember-data/system/model/model",
6914
6495
  */
6915
6496
  clearRelationships: function() {
6916
6497
  this.eachRelationship(function(name, relationship) {
6917
- if (relationship.kind === 'belongsTo') {
6918
- set(this, name, null);
6919
- } else if (relationship.kind === 'hasMany') {
6920
- var hasMany = this._relationships[name];
6921
- if (hasMany) { // relationships are created lazily
6922
- hasMany.destroy();
6923
- }
6498
+ var rel = this._relationships[name];
6499
+ if (rel){
6500
+ //TODO(Igor) figure out whether we want to clear or disconnect
6501
+ rel.clear();
6502
+ rel.destroy();
6924
6503
  }
6925
6504
  }, this);
6926
6505
  },
@@ -6935,9 +6514,9 @@ define("ember-data/system/model/model",
6935
6514
  },
6936
6515
 
6937
6516
  /**
6938
- When a find request is triggered on the store, the user can optionally passed in
6517
+ When a find request is triggered on the store, the user can optionally pass in
6939
6518
  attributes and relationships to be preloaded. These are meant to behave as if they
6940
- came back from the server, expect the user obtained them out of band and is informing
6519
+ came back from the server, except the user obtained them out of band and is informing
6941
6520
  the store of their existence. The most common use case is for supporting client side
6942
6521
  nested URLs, such as `/posts/1/comments/2` so the user can do
6943
6522
  `store.find('comment', 2, {post:1})` without having to fetch the post.
@@ -6976,15 +6555,20 @@ define("ember-data/system/model/model",
6976
6555
  _preloadHasMany: function(key, preloadValue, type) {
6977
6556
  var record = this;
6978
6557
 
6979
- forEach.call(preloadValue, function(recordToPush) {
6980
- recordToPush = record._convertStringOrNumberIntoRecord(recordToPush, type);
6981
- get(record, key).pushObject(recordToPush);
6558
+ var recordsToSet = map.call(preloadValue, function(recordToPush) {
6559
+ return record._convertStringOrNumberIntoRecord(recordToPush, type);
6982
6560
  });
6561
+ //We use the pathway of setting the hasMany as if it came from the adapter
6562
+ //because the user told us that they know this relationships exists already
6563
+ this._relationships[key].updateRecordsFromAdapter(recordsToSet);
6983
6564
  },
6984
6565
 
6985
6566
  _preloadBelongsTo: function(key, preloadValue, type){
6986
- var recordToPush = this._convertStringOrNumberIntoRecord(preloadValue, type);
6987
- set(this, key, recordToPush);
6567
+ var recordToSet = this._convertStringOrNumberIntoRecord(preloadValue, type);
6568
+
6569
+ //We use the pathway of setting the hasMany as if it came from the adapter
6570
+ //because the user told us that they know this relationships exists already
6571
+ this._relationships[key].setRecord(recordToSet);
6988
6572
  },
6989
6573
 
6990
6574
  _convertStringOrNumberIntoRecord: function(value, type) {
@@ -7059,9 +6643,7 @@ define("ember-data/system/model/model",
7059
6643
 
7060
6644
  if (!data) { return; }
7061
6645
 
7062
- this.suspendRelationshipObservers(function() {
7063
- this.notifyPropertyChange('data');
7064
- });
6646
+ this.notifyPropertyChange('data');
7065
6647
  },
7066
6648
 
7067
6649
  /**
@@ -7073,32 +6655,6 @@ define("ember-data/system/model/model",
7073
6655
  this.updateRecordArraysLater();
7074
6656
  },
7075
6657
 
7076
- dataDidChange: Ember.observer(function() {
7077
- this.reloadHasManys();
7078
- }, 'data'),
7079
-
7080
- reloadHasManys: function() {
7081
- var relationships = get(this.constructor, 'relationshipsByName');
7082
- this.updateRecordArraysLater();
7083
- relationships.forEach(function(name, relationship) {
7084
- if (this._data.links && this._data.links[name]) { return; }
7085
- if (relationship.kind === 'hasMany') {
7086
- this.hasManyDidChange(relationship.key);
7087
- }
7088
- }, this);
7089
- },
7090
-
7091
- hasManyDidChange: function(key) {
7092
- var hasMany = this._relationships[key];
7093
-
7094
- if (hasMany) {
7095
- var records = this._data[key] || [];
7096
-
7097
- set(hasMany, 'content', Ember.A(records));
7098
- set(hasMany, 'isLoaded', true);
7099
- hasMany.trigger('didLoad');
7100
- }
7101
- },
7102
6658
 
7103
6659
  /**
7104
6660
  @method updateRecordArraysLater
@@ -7126,18 +6682,9 @@ define("ember-data/system/model/model",
7126
6682
  this._data = data;
7127
6683
  }
7128
6684
 
7129
- var relationships = this._relationships;
7130
-
7131
- this.eachRelationship(function(name, rel) {
7132
- if (data.links && data.links[name]) { return; }
7133
- if (rel.options.async) { relationships[name] = null; }
7134
- });
7135
-
7136
6685
  if (data) { this.pushedData(); }
7137
6686
 
7138
- this.suspendRelationshipObservers(function() {
7139
- this.notifyPropertyChange('data');
7140
- });
6687
+ this.notifyPropertyChange('data');
7141
6688
  },
7142
6689
 
7143
6690
  materializeId: function(id) {
@@ -7152,27 +6699,6 @@ define("ember-data/system/model/model",
7152
6699
  this._data[name] = value;
7153
6700
  },
7154
6701
 
7155
- /**
7156
- @method updateHasMany
7157
- @private
7158
- @param {String} name
7159
- @param {Array} records
7160
- */
7161
- updateHasMany: function(name, records) {
7162
- this._data[name] = records;
7163
- this.hasManyDidChange(name);
7164
- },
7165
-
7166
- /**
7167
- @method updateBelongsTo
7168
- @private
7169
- @param {String} name
7170
- @param {DS.Model} record
7171
- */
7172
- updateBelongsTo: function(name, record) {
7173
- this._data[name] = record;
7174
- },
7175
-
7176
6702
  /**
7177
6703
  If the model `isDirty` this function will discard any unsaved
7178
6704
  changes
@@ -7203,48 +6729,13 @@ define("ember-data/system/model/model",
7203
6729
 
7204
6730
  this.send('rolledBack');
7205
6731
 
7206
- this.suspendRelationshipObservers(function() {
7207
- this.notifyPropertyChange('data');
7208
- });
6732
+ this.notifyPropertyChange('data');
7209
6733
  },
7210
6734
 
7211
6735
  toStringExtension: function() {
7212
6736
  return get(this, 'id');
7213
6737
  },
7214
6738
 
7215
- /**
7216
- The goal of this method is to temporarily disable specific observers
7217
- that take action in response to application changes.
7218
-
7219
- This allows the system to make changes (such as materialization and
7220
- rollback) that should not trigger secondary behavior (such as setting an
7221
- inverse relationship or marking records as dirty).
7222
-
7223
- The specific implementation will likely change as Ember proper provides
7224
- better infrastructure for suspending groups of observers, and if Array
7225
- observation becomes more unified with regular observers.
7226
-
7227
- @method suspendRelationshipObservers
7228
- @private
7229
- @param callback
7230
- @param binding
7231
- */
7232
- suspendRelationshipObservers: function(callback, binding) {
7233
- var observers = get(this.constructor, 'relationshipNames').belongsTo;
7234
- var self = this;
7235
-
7236
- try {
7237
- this._suspendedRelationships = true;
7238
- Ember._suspendObservers(self, observers, null, 'belongsToDidChange', function() {
7239
- Ember._suspendBeforeObservers(self, observers, null, 'belongsToWillChange', function() {
7240
- callback.call(binding || self);
7241
- });
7242
- });
7243
- } finally {
7244
- this._suspendedRelationships = false;
7245
- }
7246
- },
7247
-
7248
6739
  /**
7249
6740
  Save the record and persist any changes to the record to an
7250
6741
  extenal source via the adapter.
@@ -7610,18 +7101,6 @@ define("ember-data/system/model/states",
7610
7101
  @class RootState
7611
7102
  */
7612
7103
 
7613
- function hasDefinedProperties(object) {
7614
- // Ignore internal property defined by simulated `Ember.create`.
7615
- var names = Ember.keys(object);
7616
- var i, l, name;
7617
- for (i = 0, l = names.length; i < l; i++ ) {
7618
- name = names[i];
7619
- if (object.hasOwnProperty(name) && object[name]) { return true; }
7620
- }
7621
-
7622
- return false;
7623
- }
7624
-
7625
7104
  function didSetProperty(record, context) {
7626
7105
  if (context.value === context.originalValue) {
7627
7106
  delete record._attributes[context.name];
@@ -7696,12 +7175,8 @@ define("ember-data/system/model/states",
7696
7175
  loadingData: Ember.K,
7697
7176
 
7698
7177
  propertyWasReset: function(record, name) {
7699
- var stillDirty = false;
7700
-
7701
- for (var prop in record._attributes) {
7702
- stillDirty = true;
7703
- break;
7704
- }
7178
+ var length = Ember.keys(record._attributes);
7179
+ var stillDirty = length > 0;
7705
7180
 
7706
7181
  if (!stillDirty) { record.send('rolledBack'); }
7707
7182
  },
@@ -7924,10 +7399,7 @@ define("ember-data/system/model/states",
7924
7399
 
7925
7400
  loadedData: function(record) {
7926
7401
  record.transitionTo('loaded.created.uncommitted');
7927
-
7928
- record.suspendRelationshipObservers(function() {
7929
- record.notifyPropertyChange('data');
7930
- });
7402
+ record.notifyPropertyChange('data');
7931
7403
  },
7932
7404
 
7933
7405
  pushedData: function(record) {
@@ -8171,6 +7643,91 @@ define("ember-data/system/model/states",
8171
7643
 
8172
7644
  __exports__["default"] = RootState;
8173
7645
  });
7646
+ define("ember-data/system/promise_proxies",
7647
+ ["exports"],
7648
+ function(__exports__) {
7649
+ "use strict";
7650
+ var Promise = Ember.RSVP.Promise;
7651
+
7652
+ /**
7653
+ A `PromiseArray` is an object that acts like both an `Ember.Array`
7654
+ and a promise. When the promise is resolved the resulting value
7655
+ will be set to the `PromiseArray`'s `content` property. This makes
7656
+ it easy to create data bindings with the `PromiseArray` that will be
7657
+ updated when the promise resolves.
7658
+
7659
+ For more information see the [Ember.PromiseProxyMixin
7660
+ documentation](/api/classes/Ember.PromiseProxyMixin.html).
7661
+
7662
+ Example
7663
+
7664
+ ```javascript
7665
+ var promiseArray = DS.PromiseArray.create({
7666
+ promise: $.getJSON('/some/remote/data.json')
7667
+ });
7668
+
7669
+ promiseArray.get('length'); // 0
7670
+
7671
+ promiseArray.then(function() {
7672
+ promiseArray.get('length'); // 100
7673
+ });
7674
+ ```
7675
+
7676
+ @class PromiseArray
7677
+ @namespace DS
7678
+ @extends Ember.ArrayProxy
7679
+ @uses Ember.PromiseProxyMixin
7680
+ */
7681
+ var PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
7682
+
7683
+ /**
7684
+ A `PromiseObject` is an object that acts like both an `Ember.Object`
7685
+ and a promise. When the promise is resolved, then the resulting value
7686
+ will be set to the `PromiseObject`'s `content` property. This makes
7687
+ it easy to create data bindings with the `PromiseObject` that will
7688
+ be updated when the promise resolves.
7689
+
7690
+ For more information see the [Ember.PromiseProxyMixin
7691
+ documentation](/api/classes/Ember.PromiseProxyMixin.html).
7692
+
7693
+ Example
7694
+
7695
+ ```javascript
7696
+ var promiseObject = DS.PromiseObject.create({
7697
+ promise: $.getJSON('/some/remote/data.json')
7698
+ });
7699
+
7700
+ promiseObject.get('name'); // null
7701
+
7702
+ promiseObject.then(function() {
7703
+ promiseObject.get('name'); // 'Tomster'
7704
+ });
7705
+ ```
7706
+
7707
+ @class PromiseObject
7708
+ @namespace DS
7709
+ @extends Ember.ObjectProxy
7710
+ @uses Ember.PromiseProxyMixin
7711
+ */
7712
+ var PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
7713
+
7714
+ var promiseObject = function(promise, label) {
7715
+ return PromiseObject.create({
7716
+ promise: Promise.resolve(promise, label)
7717
+ });
7718
+ };
7719
+
7720
+ var promiseArray = function(promise, label) {
7721
+ return PromiseArray.create({
7722
+ promise: Promise.resolve(promise, label)
7723
+ });
7724
+ };
7725
+
7726
+ __exports__.PromiseArray = PromiseArray;
7727
+ __exports__.PromiseObject = PromiseObject;
7728
+ __exports__.promiseArray = promiseArray;
7729
+ __exports__.promiseObject = promiseObject;
7730
+ });
8174
7731
  define("ember-data/system/record_array_manager",
8175
7732
  ["ember-data/system/record_arrays","exports"],
8176
7733
  function(__dependency1__, __exports__) {
@@ -8184,7 +7741,6 @@ define("ember-data/system/record_array_manager",
8184
7741
  var AdapterPopulatedRecordArray = __dependency1__.AdapterPopulatedRecordArray;
8185
7742
  var ManyArray = __dependency1__.ManyArray;
8186
7743
  var get = Ember.get;
8187
- var set = Ember.set;
8188
7744
  var forEach = Ember.EnumerableUtils.forEach;
8189
7745
 
8190
7746
  /**
@@ -8509,7 +8065,6 @@ define("ember-data/system/record_arrays/adapter_populated_record_array",
8509
8065
  */
8510
8066
 
8511
8067
  var get = Ember.get;
8512
- var set = Ember.set;
8513
8068
 
8514
8069
  function cloneNull(source) {
8515
8070
  var clone = Object.create(null);
@@ -8635,22 +8190,16 @@ define("ember-data/system/record_arrays/filtered_record_array",
8635
8190
  });
8636
8191
  });
8637
8192
  define("ember-data/system/record_arrays/many_array",
8638
- ["ember-data/system/record_arrays/record_array","ember-data/system/changes","exports"],
8639
- function(__dependency1__, __dependency2__, __exports__) {
8193
+ ["ember-data/system/record_arrays/record_array","exports"],
8194
+ function(__dependency1__, __exports__) {
8640
8195
  "use strict";
8641
8196
  var RecordArray = __dependency1__["default"];
8642
- var RelationshipChange = __dependency2__.RelationshipChange;
8643
8197
 
8644
8198
  /**
8645
8199
  @module ember-data
8646
8200
  */
8647
8201
 
8648
8202
  var get = Ember.get, set = Ember.set;
8649
- var map = Ember.EnumerableUtils.map;
8650
-
8651
- function sync(change) {
8652
- change.sync();
8653
- }
8654
8203
 
8655
8204
  /**
8656
8205
  A `ManyArray` is a `RecordArray` that represents the contents of a has-many
@@ -8691,7 +8240,6 @@ define("ember-data/system/record_arrays/many_array",
8691
8240
  __exports__["default"] = RecordArray.extend({
8692
8241
  init: function() {
8693
8242
  this._super.apply(this, arguments);
8694
- this._changesToSync = Ember.OrderedSet.create();
8695
8243
  },
8696
8244
 
8697
8245
  /**
@@ -8722,6 +8270,16 @@ define("ember-data/system/record_arrays/many_array",
8722
8270
 
8723
8271
  isLoaded: false,
8724
8272
 
8273
+ /**
8274
+ The relationship which manages this array.
8275
+
8276
+ @property {DS.Model} owner
8277
+ @private
8278
+ */
8279
+
8280
+ relationship: null,
8281
+
8282
+
8725
8283
  /**
8726
8284
  Used for async `hasMany` arrays
8727
8285
  to keep track of when they will resolve.
@@ -8752,98 +8310,14 @@ define("ember-data/system/record_arrays/many_array",
8752
8310
  }
8753
8311
  },
8754
8312
 
8755
- /**
8756
- @method fetch
8757
- @private
8758
- */
8759
- fetch: function() {
8760
- var records = get(this, 'content');
8761
- var store = get(this, 'store');
8762
- var owner = get(this, 'owner');
8763
-
8764
- var unloadedRecords = records.filterBy('isEmpty', true);
8765
- store.scheduleFetchMany(unloadedRecords, owner);
8766
- },
8767
-
8768
- // Overrides Ember.Array's replace method to implement
8769
- replaceContent: function(index, removed, added) {
8770
- // Map the array of record objects into an array of client ids.
8771
- added = map(added, function(record) {
8772
- return record;
8773
- }, this);
8774
-
8775
- this._super(index, removed, added);
8776
- },
8777
-
8778
- arrangedContentDidChange: function() {
8779
- Ember.run.once(this, 'fetch');
8780
- },
8781
-
8782
- arrayContentWillChange: function(index, removed, added) {
8783
- var owner = get(this, 'owner');
8784
- var name = get(this, 'name');
8785
-
8786
- if (!owner._suspendedRelationships) {
8787
- // This code is the first half of code that continues inside
8788
- // of arrayContentDidChange. It gets or creates a change from
8789
- // the child object, adds the current owner as the old
8790
- // parent if this is the first time the object was removed
8791
- // from a ManyArray, and sets `newParent` to null.
8792
- //
8793
- // Later, if the object is added to another ManyArray,
8794
- // the `arrayContentDidChange` will set `newParent` on
8795
- // the change.
8796
- for (var i=index; i<index+removed; i++) {
8797
- var record = get(this, 'content').objectAt(i);
8798
-
8799
- var change = RelationshipChange.createChange(owner, record, get(this, 'store'), {
8800
- parentType: owner.constructor,
8801
- changeType: "remove",
8802
- kind: "hasMany",
8803
- key: name
8804
- });
8805
-
8806
- this._changesToSync.add(change);
8807
- }
8313
+ replaceContent: function(idx, amt, objects){
8314
+ var records;
8315
+ if (amt > 0){
8316
+ records = get(this, 'content').slice(idx, idx+amt);
8317
+ this.get('relationship').removeRecords(records);
8808
8318
  }
8809
-
8810
- return this._super.apply(this, arguments);
8811
- },
8812
-
8813
- arrayContentDidChange: function(index, removed, added) {
8814
- this._super.apply(this, arguments);
8815
-
8816
- var owner = get(this, 'owner');
8817
- var name = get(this, 'name');
8818
- var store = get(this, 'store');
8819
-
8820
- if (!owner._suspendedRelationships) {
8821
- // This code is the second half of code that started in
8822
- // `arrayContentWillChange`. It gets or creates a change
8823
- // from the child object, and adds the current owner as
8824
- // the new parent.
8825
- for (var i=index; i<index+added; i++) {
8826
- var record = get(this, 'content').objectAt(i);
8827
-
8828
- var change = RelationshipChange.createChange(owner, record, store, {
8829
- parentType: owner.constructor,
8830
- changeType: "add",
8831
- kind:"hasMany",
8832
- key: name
8833
- });
8834
- change.hasManyName = name;
8835
-
8836
- this._changesToSync.add(change);
8837
- }
8838
-
8839
- // We wait until the array has finished being
8840
- // mutated before syncing the OneToManyChanges created
8841
- // in arrayContentWillChange, so that the array
8842
- // membership test in the sync() logic operates
8843
- // on the final results.
8844
- this._changesToSync.forEach(sync);
8845
-
8846
- this._changesToSync.clear();
8319
+ if (objects){
8320
+ this.get('relationship').addRecords(objects, idx);
8847
8321
  }
8848
8322
  },
8849
8323
 
@@ -8856,8 +8330,7 @@ define("ember-data/system/record_arrays/many_array",
8856
8330
  @return {DS.Model} record
8857
8331
  */
8858
8332
  createRecord: function(hash) {
8859
- var owner = get(this, 'owner');
8860
- var store = get(owner, 'store');
8333
+ var store = get(this, 'store');
8861
8334
  var type = get(this, 'type');
8862
8335
  var record;
8863
8336
 
@@ -8870,7 +8343,7 @@ define("ember-data/system/record_arrays/many_array",
8870
8343
  });
8871
8344
  });
8872
8345
  define("ember-data/system/record_arrays/record_array",
8873
- ["ember-data/system/store","exports"],
8346
+ ["ember-data/system/promise_proxies","exports"],
8874
8347
  function(__dependency1__, __exports__) {
8875
8348
  "use strict";
8876
8349
  /**
@@ -8879,7 +8352,6 @@ define("ember-data/system/record_arrays/record_array",
8879
8352
 
8880
8353
  var PromiseArray = __dependency1__.PromiseArray;
8881
8354
  var get = Ember.get;
8882
- var set = Ember.set;
8883
8355
 
8884
8356
  /**
8885
8357
  A record array is an array that contains records of a certain type. The record
@@ -8999,9 +8471,17 @@ define("ember-data/system/record_arrays/record_array",
8999
8471
  @method addRecord
9000
8472
  @private
9001
8473
  @param {DS.Model} record
8474
+ @param {DS.Model} an optional index to insert at
9002
8475
  */
9003
- addRecord: function(record) {
9004
- get(this, 'content').addObject(record);
8476
+ addRecord: function(record, idx) {
8477
+ var content = get(this, 'content');
8478
+ if (idx === undefined) {
8479
+ content.addObject(record);
8480
+ } else {
8481
+ if (!content.contains(record)) {
8482
+ content.insertAt(idx, record);
8483
+ }
8484
+ }
9005
8485
  },
9006
8486
 
9007
8487
  /**
@@ -9103,14 +8583,7 @@ define("ember-data/system/relationship-meta",
9103
8583
  };
9104
8584
  }
9105
8585
 
9106
- __exports__.relationshipFromMeta = relationshipFromMeta;function isSyncRelationship(record, relationshipName) {
9107
- var meta = Ember.meta(record);
9108
- var desc = meta.descs[relationshipName];
9109
-
9110
- return desc && !desc._meta.options.async;
9111
- }
9112
-
9113
- __exports__.isSyncRelationship = isSyncRelationship;
8586
+ __exports__.relationshipFromMeta = relationshipFromMeta;
9114
8587
  });
9115
8588
  define("ember-data/system/relationships",
9116
8589
  ["./relationships/belongs_to","./relationships/has_many","ember-data/system/relationships/ext","exports"],
@@ -9128,64 +8601,11 @@ define("ember-data/system/relationships",
9128
8601
  __exports__.hasMany = hasMany;
9129
8602
  });
9130
8603
  define("ember-data/system/relationships/belongs_to",
9131
- ["ember-data/system/model","ember-data/system/store","ember-data/system/changes","ember-data/system/relationship-meta","exports"],
9132
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
8604
+ ["ember-data/system/model","exports"],
8605
+ function(__dependency1__, __exports__) {
9133
8606
  "use strict";
9134
- var get = Ember.get;
9135
- var set = Ember.set;
9136
- var isNone = Ember.isNone;
9137
- var Promise = Ember.RSVP.Promise;
9138
-
9139
8607
  var Model = __dependency1__.Model;
9140
- var PromiseObject = __dependency2__.PromiseObject;
9141
- var RelationshipChange = __dependency3__.RelationshipChange;
9142
- var relationshipFromMeta = __dependency4__.relationshipFromMeta;
9143
- var typeForRelationshipMeta = __dependency4__.typeForRelationshipMeta;
9144
- var isSyncRelationship = __dependency4__.isSyncRelationship;
9145
-
9146
- /**
9147
- @module ember-data
9148
- */
9149
-
9150
- function asyncBelongsTo(type, options, meta) {
9151
- return Ember.computed('data', function(key, value) {
9152
- var data = get(this, 'data');
9153
- var store = get(this, 'store');
9154
- var promiseLabel = "DS: Async belongsTo " + this + " : " + key;
9155
- var promise;
9156
-
9157
- meta.key = key;
9158
8608
 
9159
- if (arguments.length === 2) {
9160
- return value === undefined ? null : PromiseObject.create({
9161
- promise: Promise.cast(value, promiseLabel)
9162
- });
9163
- }
9164
-
9165
- var link = data.links && data.links[key];
9166
- var belongsTo = data[key];
9167
-
9168
- if (!isNone(belongsTo)) {
9169
- var inverse = this.constructor.inverseFor(key);
9170
- //but for now only in the oneToOne case
9171
- if (inverse && inverse.kind === 'belongsTo'){
9172
- set(belongsTo, inverse.name, this);
9173
- }
9174
- //TODO(Igor) after OR doesn't seem that will be called
9175
- promise = store.findById(belongsTo.constructor, belongsTo.get('id')) || Promise.cast(belongsTo, promiseLabel);
9176
- return PromiseObject.create({
9177
- promise: promise
9178
- });
9179
- } else if (link) {
9180
- promise = store.findBelongsTo(this, link, relationshipFromMeta(store, meta));
9181
- return PromiseObject.create({
9182
- promise: promise
9183
- });
9184
- } else {
9185
- return null;
9186
- }
9187
- }).meta(meta);
9188
- }
9189
8609
 
9190
8610
  /**
9191
8611
  `DS.belongsTo` is used to define One-To-One and One-To-Many
@@ -9251,32 +8671,15 @@ define("ember-data/system/relationships/belongs_to",
9251
8671
  key: null
9252
8672
  };
9253
8673
 
9254
- if (options.async) {
9255
- return asyncBelongsTo(type, options, meta);
9256
- }
9257
-
9258
- return Ember.computed('data', function(key, value) {
9259
- var data = get(this, 'data');
9260
- var store = get(this, 'store');
9261
- var belongsTo, typeClass;
9262
-
9263
- if (typeof type === 'string') {
9264
- typeClass = store.modelFor(type);
9265
- } else {
9266
- typeClass = type;
9267
- }
9268
-
9269
- if (arguments.length === 2) {
9270
- return value === undefined ? null : value;
8674
+ return Ember.computed(function(key, value) {
8675
+ if (arguments.length>1) {
8676
+ if ( value === undefined ) {
8677
+ value = null;
8678
+ }
8679
+ this._relationships[key].setRecord(value);
9271
8680
  }
9272
8681
 
9273
- belongsTo = data[key];
9274
-
9275
- if (isNone(belongsTo)) { return null; }
9276
-
9277
- store.findById(belongsTo.constructor, belongsTo.get('id'));
9278
-
9279
- return belongsTo;
8682
+ return this._relationships[key].getRecord();
9280
8683
  }).meta(meta);
9281
8684
  }
9282
8685
 
@@ -9288,72 +8691,26 @@ define("ember-data/system/relationships/belongs_to",
9288
8691
  @namespace DS
9289
8692
  */
9290
8693
  Model.reopen({
8694
+ notifyBelongsToAdded: function(key, relationship) {
8695
+ this.notifyPropertyChange(key);
8696
+ },
9291
8697
 
9292
- /**
9293
- @method belongsToWillChange
9294
- @private
9295
- @static
9296
- @param record
9297
- @param key
9298
- */
9299
- belongsToWillChange: Ember.beforeObserver(function(record, key) {
9300
- if (get(record, 'isLoaded') && isSyncRelationship(record, key)) {
9301
- var oldParent = get(record, key);
9302
-
9303
- if (oldParent) {
9304
- var store = get(record, 'store');
9305
- var change = RelationshipChange.createChange(record, oldParent, store, {
9306
- key: key,
9307
- kind: 'belongsTo',
9308
- changeType: 'remove'
9309
- });
9310
-
9311
- change.sync();
9312
- this._changesToSync[key] = change;
9313
- }
9314
- }
9315
- }),
9316
-
9317
- /**
9318
- @method belongsToDidChange
9319
- @private
9320
- @static
9321
- @param record
9322
- @param key
9323
- */
9324
- belongsToDidChange: Ember.immediateObserver(function(record, key) {
9325
- if (get(record, 'isLoaded')) {
9326
- var newParent = get(record, key);
9327
-
9328
- if (newParent) {
9329
- var store = get(record, 'store');
9330
- var change = RelationshipChange.createChange(record, newParent, store, {
9331
- key: key,
9332
- kind: 'belongsTo',
9333
- changeType: 'add'
9334
- });
9335
-
9336
- change.sync();
9337
- }
9338
- }
9339
-
9340
- delete this._changesToSync[key];
9341
- })
8698
+ notifyBelongsToRemoved: function(key) {
8699
+ this.notifyPropertyChange(key);
8700
+ }
9342
8701
  });
9343
8702
 
9344
8703
  __exports__["default"] = belongsTo;
9345
8704
  });
9346
8705
  define("ember-data/system/relationships/ext",
9347
- ["ember-inflector/system","ember-data/system/relationship-meta","ember-data/system/model"],
9348
- function(__dependency1__, __dependency2__, __dependency3__) {
8706
+ ["ember-data/system/relationship-meta","ember-data/system/model"],
8707
+ function(__dependency1__, __dependency2__) {
9349
8708
  "use strict";
9350
- var singularize = __dependency1__.singularize;
9351
- var typeForRelationshipMeta = __dependency2__.typeForRelationshipMeta;
9352
- var relationshipFromMeta = __dependency2__.relationshipFromMeta;
9353
- var Model = __dependency3__.Model;
8709
+ var typeForRelationshipMeta = __dependency1__.typeForRelationshipMeta;
8710
+ var relationshipFromMeta = __dependency1__.relationshipFromMeta;
8711
+ var Model = __dependency2__.Model;
9354
8712
 
9355
8713
  var get = Ember.get;
9356
- var set = Ember.set;
9357
8714
 
9358
8715
  /**
9359
8716
  @module ember-data
@@ -9405,11 +8762,6 @@ define("ember-data/system/relationships/ext",
9405
8762
  // the computed property.
9406
8763
  var meta = value.meta();
9407
8764
 
9408
- if (meta.isRelationship && meta.kind === 'belongsTo') {
9409
- Ember.addObserver(proto, key, null, 'belongsToDidChange');
9410
- Ember.addBeforeObserver(proto, key, null, 'belongsToWillChange');
9411
- }
9412
-
9413
8765
  meta.parentType = proto.constructor;
9414
8766
  }
9415
8767
  }
@@ -9784,7 +9136,28 @@ define("ember-data/system/relationships/ext",
9784
9136
  get(this, 'relatedTypes').forEach(function(type) {
9785
9137
  callback.call(binding, type);
9786
9138
  });
9139
+ },
9140
+
9141
+ determineRelationshipType: function(knownSide) {
9142
+ var knownKey = knownSide.key;
9143
+ var knownKind = knownSide.kind;
9144
+ var inverse = this.inverseFor(knownKey);
9145
+ var key, otherKind;
9146
+
9147
+ if (!inverse) {
9148
+ return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
9149
+ }
9150
+
9151
+ key = inverse.name;
9152
+ otherKind = inverse.kind;
9153
+
9154
+ if (otherKind === 'belongsTo') {
9155
+ return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
9156
+ } else {
9157
+ return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
9158
+ }
9787
9159
  }
9160
+
9788
9161
  });
9789
9162
 
9790
9163
  Model.reopen({
@@ -9799,124 +9172,27 @@ define("ember-data/system/relationships/ext",
9799
9172
  */
9800
9173
  eachRelationship: function(callback, binding) {
9801
9174
  this.constructor.eachRelationship(callback, binding);
9175
+ },
9176
+
9177
+ relationshipFor: function(name) {
9178
+ return get(this.constructor, 'relationshipsByName').get(name);
9179
+ },
9180
+
9181
+ inverseFor: function(key) {
9182
+ return this.constructor.inverseFor(key);
9802
9183
  }
9184
+
9803
9185
  });
9804
9186
  });
9805
9187
  define("ember-data/system/relationships/has_many",
9806
- ["ember-data/system/store","ember-data/system/relationship-meta","exports"],
9807
- function(__dependency1__, __dependency2__, __exports__) {
9188
+ ["ember-data/system/model","exports"],
9189
+ function(__dependency1__, __exports__) {
9808
9190
  "use strict";
9809
9191
  /**
9810
9192
  @module ember-data
9811
9193
  */
9812
9194
 
9813
- var PromiseArray = __dependency1__.PromiseArray;
9814
-
9815
- var relationshipFromMeta = __dependency2__.relationshipFromMeta;
9816
- var typeForRelationshipMeta = __dependency2__.typeForRelationshipMeta;
9817
-
9818
- var get = Ember.get;
9819
- var set = Ember.set;
9820
- var setProperties = Ember.setProperties;
9821
- var map = Ember.EnumerableUtils.map;
9822
-
9823
- /**
9824
- Returns a computed property that synchronously returns a ManyArray for
9825
- this relationship. If not all of the records in this relationship are
9826
- loaded, it will raise an exception.
9827
- */
9828
-
9829
- function syncHasMany(type, options, meta) {
9830
- return Ember.computed('data', function(key) {
9831
- return buildRelationship(this, key, options, function(store, data) {
9832
- // Configure the metadata for the computed property to contain
9833
- // the key.
9834
- meta.key = key;
9835
-
9836
- var records = data[key];
9837
-
9838
-
9839
- return store.findMany(this, data[key], typeForRelationshipMeta(store, meta));
9840
- });
9841
- }).meta(meta).readOnly();
9842
- }
9843
-
9844
- /**
9845
- Returns a computed property that itself returns a promise that resolves to a
9846
- ManyArray.
9847
- */
9848
-
9849
- function asyncHasMany(type, options, meta) {
9850
- return Ember.computed('data', function(key) {
9851
- // Configure the metadata for the computed property to contain
9852
- // the key.
9853
- meta.key = key;
9854
-
9855
- var relationship = buildRelationship(this, key, options, function(store, data) {
9856
- var link = data.links && data.links[key];
9857
- var rel;
9858
- var promiseLabel = "DS: Async hasMany " + this + " : " + key;
9859
- var resolver = Ember.RSVP.defer(promiseLabel);
9860
-
9861
- if (link) {
9862
- rel = store.findHasMany(this, link, relationshipFromMeta(store, meta), resolver);
9863
- } else {
9864
-
9865
- //This is a temporary workaround for setting owner on the relationship
9866
- //until single source of truth lands. It only works for OneToMany atm
9867
- var records = data[key];
9868
- var inverse = this.constructor.inverseFor(key);
9869
- var owner = this;
9870
- if (inverse && records) {
9871
- if (inverse.kind === 'belongsTo'){
9872
- map(records, function(record){
9873
- set(record, inverse.name, owner);
9874
- });
9875
- }
9876
- }
9877
-
9878
- rel = store.findMany(owner, data[key], typeForRelationshipMeta(store, meta), resolver);
9879
- }
9880
-
9881
- // Cache the promise so we can use it when we come back and don't
9882
- // need to rebuild the relationship.
9883
- set(rel, 'promise', resolver.promise);
9884
-
9885
- return rel;
9886
- });
9887
-
9888
- var promise = relationship.get('promise').then(function() {
9889
- return relationship;
9890
- }, null, "DS: Async hasMany records received");
9891
-
9892
- return PromiseArray.create({
9893
- promise: promise
9894
- });
9895
- }).meta(meta).readOnly();
9896
- }
9897
-
9898
- /*
9899
- Builds the ManyArray for a relationship using the provided callback,
9900
- but only if it had not been created previously. After building, it
9901
- sets some metadata on the created ManyArray, such as the record which
9902
- owns it and the name of the relationship.
9903
- */
9904
- function buildRelationship(record, key, options, callback) {
9905
- var rels = record._relationships;
9906
-
9907
- if (rels[key]) { return rels[key]; }
9908
-
9909
- var data = get(record, 'data');
9910
- var store = get(record, 'store');
9911
-
9912
- var relationship = rels[key] = callback.call(record, store, data);
9913
-
9914
- return setProperties(relationship, {
9915
- owner: record,
9916
- name: key,
9917
- isPolymorphic: options.polymorphic
9918
- });
9919
- }
9195
+ var Model = __dependency1__.Model;
9920
9196
 
9921
9197
  /**
9922
9198
  `DS.hasMany` is used to define One-To-Many and Many-To-Many
@@ -10016,18 +9292,313 @@ define("ember-data/system/relationships/has_many",
10016
9292
  key: null
10017
9293
  };
10018
9294
 
10019
- if (options.async) {
10020
- return asyncHasMany(type, options, meta);
9295
+ return Ember.computed(function(key) {
9296
+ var relationship = this._relationships[key];
9297
+ return relationship.getRecords();
9298
+ }).meta(meta).readOnly();
9299
+ }
9300
+
9301
+ Model.reopen({
9302
+ notifyHasManyAdded: function(key, record, idx) {
9303
+ var relationship = this._relationships[key];
9304
+ var manyArray = relationship.manyArray;
9305
+ manyArray.addRecord(record, idx);
9306
+ //We need to notifyPropertyChange in the adding case because we need to make sure
9307
+ //we fetch the newly added record in case it is unloaded
9308
+ //TODO(Igor): Consider whether we could do this only if the record state is unloaded
9309
+ this.notifyPropertyChange(key);
9310
+ },
9311
+
9312
+ notifyHasManyRemoved: function(key, record) {
9313
+ var relationship = this._relationships[key];
9314
+ var manyArray = relationship.manyArray;
9315
+ manyArray.removeRecord(record);
9316
+ }
9317
+ });
9318
+
9319
+
9320
+ __exports__["default"] = hasMany;
9321
+ });
9322
+ define("ember-data/system/relationships/relationship",
9323
+ ["ember-data/system/promise_proxies","exports"],
9324
+ function(__dependency1__, __exports__) {
9325
+ "use strict";
9326
+ var PromiseArray = __dependency1__.PromiseArray;
9327
+ var PromiseObject = __dependency1__.PromiseObject;
9328
+
9329
+ var Relationship = function(store, record, inverseKey, relationshipMeta) {
9330
+ this.members = new Ember.OrderedSet();
9331
+ this.store = store;
9332
+ this.key = relationshipMeta.key;
9333
+ this.inverseKey = inverseKey;
9334
+ this.record = record;
9335
+ this.key = relationshipMeta.key;
9336
+ this.isAsync = relationshipMeta.options.async;
9337
+ this.relationshipMeta = relationshipMeta;
9338
+ };
9339
+
9340
+ Relationship.prototype = {
9341
+ constructor: Relationship,
9342
+ hasFetchedLink: false,
9343
+
9344
+ destroy: Ember.K,
9345
+
9346
+ clear: function() {
9347
+ this.members.forEach(function(member) {
9348
+ this.removeRecord(member);
9349
+ }, this);
9350
+ },
9351
+
9352
+ removeRecords: function(records){
9353
+ var that = this;
9354
+ records.forEach(function(record){
9355
+ that.removeRecord(record);
9356
+ });
9357
+ },
9358
+
9359
+ addRecords: function(records, idx){
9360
+ var that = this;
9361
+ records.forEach(function(record){
9362
+ that.addRecord(record, idx);
9363
+ if (idx !== undefined) {
9364
+ idx++;
9365
+ }
9366
+ });
9367
+ },
9368
+
9369
+
9370
+ addRecord: function(record, idx) {
9371
+ if (!this.members.has(record)) {
9372
+ this.members.add(record);
9373
+ this.notifyRecordRelationshipAdded(record, idx);
9374
+ if (this.inverseKey) {
9375
+ record._relationships[this.inverseKey].addRecord(this.record);
9376
+ }
9377
+ this.record.updateRecordArrays();
9378
+ }
9379
+ },
9380
+
9381
+ removeRecord: function(record) {
9382
+ if (this.members.has(record)) {
9383
+ this.members.remove(record);
9384
+ this.notifyRecordRelationshipRemoved(record);
9385
+ if (this.inverseKey) {
9386
+ var inverseRelationship = record._relationships[this.inverseKey];
9387
+ //Need to check for existence, as the record might unloading at the moment
9388
+ if (inverseRelationship) {
9389
+ inverseRelationship.removeRecord(this.record);
9390
+ }
9391
+ }
9392
+ this.record.updateRecordArrays();
9393
+ }
9394
+ },
9395
+
9396
+ updateLink: function(link) {
9397
+ if (link !== this.link) {
9398
+ this.link = link;
9399
+ this.hasFetchedLink = false;
9400
+ this.record.notifyPropertyChange(this.key);
9401
+ }
9402
+ },
9403
+
9404
+ updateRecordsFromAdapter: function(records) {
9405
+ //TODO Once we have adapter support, we need to handle updated and canonical changes
9406
+ this.computeChanges(records);
9407
+ }
9408
+ };
9409
+
9410
+ var ManyRelationship = function(store, record, inverseKey, relationshipMeta) {
9411
+ this._super$constructor(store, record, inverseKey, relationshipMeta);
9412
+ this.belongsToType = relationshipMeta.type;
9413
+ this.manyArray = store.recordArrayManager.createManyArray(this.belongsToType, Ember.A());
9414
+ this.manyArray.relationship = this;
9415
+ this.isPolymorphic = relationshipMeta.options.polymorphic;
9416
+ this.manyArray.isPolymorphic = this.isPolymorphic;
9417
+ };
9418
+
9419
+ ManyRelationship.prototype = Object.create(Relationship.prototype);
9420
+ ManyRelationship.prototype.constructor = ManyRelationship;
9421
+ ManyRelationship.prototype._super$constructor = Relationship;
9422
+
9423
+ ManyRelationship.prototype.destroy = function() {
9424
+ this.manyArray.destroy();
9425
+ };
9426
+
9427
+ ManyRelationship.prototype.notifyRecordRelationshipAdded = function(record, idx) {
9428
+ this.record.notifyHasManyAdded(this.key, record, idx);
9429
+ };
9430
+
9431
+ ManyRelationship.prototype.notifyRecordRelationshipRemoved = function(record) {
9432
+ this.record.notifyHasManyRemoved(this.key, record);
9433
+ };
9434
+
9435
+ ManyRelationship.prototype.computeChanges = function(records) {
9436
+ var members = this.members;
9437
+
9438
+ records = setForArray(records);
9439
+
9440
+ members.forEach(function(member) {
9441
+ if (records.has(member)) return;
9442
+
9443
+ this.removeRecord(member);
9444
+ }, this);
9445
+
9446
+ var hasManyArray = this.manyArray;
9447
+
9448
+ records.forEach(function(record, index) {
9449
+ //Need to preserve the order of incoming records
9450
+ if (hasManyArray.objectAt(index) === record ) return;
9451
+
9452
+ this.removeRecord(record);
9453
+ this.addRecord(record, index);
9454
+ }, this);
9455
+ };
9456
+
9457
+
9458
+ ManyRelationship.prototype.getRecords = function() {
9459
+ if (this.isAsync) {
9460
+ var self = this;
9461
+ var promise;
9462
+ if (this.link && !this.hasFetchedLink) {
9463
+ promise = this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records){
9464
+ self.updateRecordsFromAdapter(records);
9465
+ self.hasFetchedLink = true;
9466
+ //TODO(Igor) try to abstract the isLoaded part
9467
+ self.manyArray.set('isLoaded', true);
9468
+ return self.manyArray;
9469
+ });
9470
+ } else {
9471
+ var manyArray = this.manyArray;
9472
+ promise = this.store.findMany(manyArray.toArray()).then(function(){
9473
+ self.manyArray.set('isLoaded', true);
9474
+ return manyArray;
9475
+ });
9476
+ }
9477
+ return PromiseArray.create({
9478
+ promise: promise
9479
+ });
9480
+ } else {
9481
+
9482
+ this.manyArray.set('isLoaded', true);
9483
+ return this.manyArray;
9484
+ }
9485
+ };
9486
+
9487
+ var BelongsToRelationship = function(store, record, inverseKey, relationshipMeta) {
9488
+ this._super$constructor(store, record, inverseKey, relationshipMeta);
9489
+ this.members.add(record);
9490
+ this.record = record;
9491
+ this.key = relationshipMeta.key;
9492
+ this.inverseKey = inverseKey;
9493
+ this.inverseRecord = null;
9494
+ };
9495
+
9496
+ BelongsToRelationship.prototype = Object.create(Relationship.prototype);
9497
+ BelongsToRelationship.prototype.constructor = BelongsToRelationship;
9498
+ BelongsToRelationship.prototype._super$constructor = Relationship;
9499
+
9500
+ BelongsToRelationship.prototype.setRecord = function(newRecord) {
9501
+ if (newRecord) {
9502
+ this.addRecord(newRecord);
9503
+ } else if (this.inverseRecord) {
9504
+ this.removeRecord(this.inverseRecord);
9505
+ }
9506
+ };
9507
+
9508
+ BelongsToRelationship.prototype._super$addRecord = Relationship.prototype.addRecord;
9509
+ BelongsToRelationship.prototype.addRecord = function(newRecord) {
9510
+ if (this.members.has(newRecord)){ return;}
9511
+ var type = this.relationshipMeta.type;
9512
+
9513
+ if (this.inverseRecord && this.inverseKey) {
9514
+ this.removeRecord(this.inverseRecord);
9515
+ }
9516
+
9517
+ this.inverseRecord = newRecord;
9518
+ this._super$addRecord(newRecord);
9519
+ };
9520
+
9521
+ BelongsToRelationship.prototype.notifyRecordRelationshipAdded = function(newRecord) {
9522
+ this.record.notifyBelongsToAdded(this.key, this);
9523
+ };
9524
+
9525
+ BelongsToRelationship.prototype.notifyRecordRelationshipRemoved = function(record) {
9526
+ this.record.notifyBelongsToRemoved(this.key, this);
9527
+ };
9528
+
9529
+ BelongsToRelationship.prototype._super$removeRecord = Relationship.prototype.removeRecord;
9530
+ BelongsToRelationship.prototype.removeRecord = function(record) {
9531
+ if (!this.members.has(record)){ return;}
9532
+ this._super$removeRecord(record);
9533
+ this.inverseRecord = null;
9534
+ };
9535
+
9536
+ BelongsToRelationship.prototype.currentOtherSideFor = function() {
9537
+ return this.inverseRecord;
9538
+ };
9539
+
9540
+ BelongsToRelationship.prototype.getRecord = function() {
9541
+ if (this.isAsync) {
9542
+ var promise;
9543
+
9544
+ if (this.link && !this.hasFetchedLink){
9545
+ var self = this;
9546
+ promise = this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record){
9547
+ self.addRecord(record);
9548
+ self.hasFetchedLink = true;
9549
+ return record;
9550
+ });
9551
+ } else if (this.inverseRecord) {
9552
+ promise = this.store._findByRecord(this.inverseRecord);
9553
+ } else {
9554
+ promise = Ember.RSVP.Promise.resolve(null);
9555
+ }
9556
+
9557
+ return PromiseObject.create({
9558
+ promise: promise
9559
+ });
10021
9560
  } else {
10022
- return syncHasMany(type, options, meta);
9561
+ return this.inverseRecord;
9562
+ }
9563
+ };
9564
+
9565
+ function setForArray(array) {
9566
+ var set = new Ember.OrderedSet();
9567
+
9568
+ if (array) {
9569
+ for (var i=0, l=array.length; i<l; i++) {
9570
+ set.add(array[i]);
9571
+ }
10023
9572
  }
9573
+
9574
+ return set;
10024
9575
  }
10025
9576
 
10026
- __exports__["default"] = hasMany;
9577
+ var createRelationshipFor = function(record, relationshipMeta, store){
9578
+ var inverseKey;
9579
+ var inverse = record.constructor.inverseFor(relationshipMeta.key);
9580
+
9581
+ if (inverse) {
9582
+ inverseKey = inverse.name;
9583
+ }
9584
+
9585
+ if (relationshipMeta.kind === 'hasMany'){
9586
+ return new ManyRelationship(store, record, inverseKey, relationshipMeta);
9587
+ }
9588
+ else {
9589
+ return new BelongsToRelationship(store, record, inverseKey, relationshipMeta);
9590
+ }
9591
+ };
9592
+
9593
+
9594
+ __exports__.Relationship = Relationship;
9595
+ __exports__.ManyRelationship = ManyRelationship;
9596
+ __exports__.BelongsToRelationship = BelongsToRelationship;
9597
+ __exports__.createRelationshipFor = createRelationshipFor;
10027
9598
  });
10028
9599
  define("ember-data/system/store",
10029
- ["ember-data/system/adapter","ember-inflector/system/string","exports"],
10030
- function(__dependency1__, __dependency2__, __exports__) {
9600
+ ["ember-data/system/adapter","ember-inflector/system/string","ember-data/system/promise_proxies","exports"],
9601
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
10031
9602
  "use strict";
10032
9603
  /*globals Ember*/
10033
9604
  /*jshint eqnull:true*/
@@ -10040,6 +9611,10 @@ define("ember-data/system/store",
10040
9611
  var Adapter = __dependency1__.Adapter;
10041
9612
  var singularize = __dependency2__.singularize;
10042
9613
 
9614
+ var promiseArray = __dependency3__.promiseArray;
9615
+ var promiseObject = __dependency3__.promiseObject;
9616
+
9617
+
10043
9618
  var get = Ember.get;
10044
9619
  var set = Ember.set;
10045
9620
  var once = Ember.run.once;
@@ -10049,7 +9624,7 @@ define("ember-data/system/store",
10049
9624
  var map = Ember.EnumerableUtils.map;
10050
9625
  var Promise = Ember.RSVP.Promise;
10051
9626
  var copy = Ember.copy;
10052
- var Store, PromiseObject, PromiseArray, RecordArrayManager, Model;
9627
+ var Store, RecordArrayManager, Model;
10053
9628
 
10054
9629
  var camelize = Ember.String.camelize;
10055
9630
 
@@ -10170,7 +9745,6 @@ define("ember-data/system/store",
10170
9745
  this.recordArrayManager = RecordArrayManager.create({
10171
9746
  store: this
10172
9747
  });
10173
- this._relationshipChanges = {};
10174
9748
  this._pendingSave = [];
10175
9749
  //Used to keep track of all the find requests that need to be coalesced
10176
9750
  this._pendingFetch = Ember.Map.create();
@@ -10381,10 +9955,10 @@ define("ember-data/system/store",
10381
9955
 
10382
9956
  ---
10383
9957
 
10384
- You can optionally preload specific attributes and relationships that you know of
9958
+ You can optionally `preload` specific attributes and relationships that you know of
10385
9959
  by passing them as the third argument to find.
10386
9960
 
10387
- For example, if your Ember route looks like `/posts/1/comments/2` and you API route
9961
+ For example, if your Ember route looks like `/posts/1/comments/2` and your API route
10388
9962
  for the comment also looks like `/posts/1/comments/2` if you want to fetch the comment
10389
9963
  without fetching the post you can pass in the post to the `find` call:
10390
9964
 
@@ -10432,6 +10006,7 @@ define("ember-data/system/store",
10432
10006
  @method find
10433
10007
  @param {String or subclass of DS.Model} type
10434
10008
  @param {Object|String|Integer|null} id
10009
+ @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
10435
10010
  @return {Promise} promise
10436
10011
  */
10437
10012
  find: function(type, id, preload) {
@@ -10455,14 +10030,20 @@ define("ember-data/system/store",
10455
10030
  @private
10456
10031
  @param {String or subclass of DS.Model} type
10457
10032
  @param {String|Integer} id
10033
+ @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
10458
10034
  @return {Promise} promise
10459
10035
  */
10460
10036
  findById: function(typeName, id, preload) {
10461
- var fetchedRecord;
10462
10037
 
10463
10038
  var type = this.modelFor(typeName);
10464
10039
  var record = this.recordForId(type, id);
10465
10040
 
10041
+ return this._findByRecord(record, preload);
10042
+ },
10043
+
10044
+ _findByRecord: function(record, preload) {
10045
+ var fetchedRecord;
10046
+
10466
10047
  if (preload) {
10467
10048
  record._preloadData(preload);
10468
10049
  }
@@ -10474,7 +10055,7 @@ define("ember-data/system/store",
10474
10055
  fetchedRecord = record._loadingPromise;
10475
10056
  }
10476
10057
 
10477
- return promiseObject(fetchedRecord || record, "DS: Store#findById " + type + " with id: " + id);
10058
+ return promiseObject(fetchedRecord || record, "DS: Store#findByRecord " + record.typeKey + " with id: " + get(record, 'id'));
10478
10059
  },
10479
10060
 
10480
10061
  /**
@@ -10489,7 +10070,6 @@ define("ember-data/system/store",
10489
10070
  */
10490
10071
  findByIds: function(type, ids) {
10491
10072
  var store = this;
10492
- var promiseLabel = "DS: Store#findByIds " + type;
10493
10073
 
10494
10074
  return promiseArray(Ember.RSVP.all(map(ids, function(id) {
10495
10075
  return store.findById(type, id);
@@ -10558,7 +10138,6 @@ define("ember-data/system/store",
10558
10138
  var adapter = store.adapterFor(type);
10559
10139
  var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
10560
10140
  var records = Ember.A(recordResolverPairs).mapBy('record');
10561
- var resolvers = Ember.A(recordResolverPairs).mapBy('resolver');
10562
10141
 
10563
10142
  function _fetchRecord(recordResolverPair) {
10564
10143
  recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record));
@@ -10715,29 +10294,14 @@ define("ember-data/system/store",
10715
10294
  @param {Resolver} resolver
10716
10295
  @return {DS.ManyArray} records
10717
10296
  */
10718
- findMany: function(owner, inputRecords, typeName, resolver) {
10719
- var type = this.modelFor(typeName);
10720
- var records = Ember.A(inputRecords);
10721
- var unloadedRecords = records.filterProperty('isEmpty', true);
10722
- var manyArray = this.recordArrayManager.createManyArray(type, records);
10723
-
10724
- manyArray.loadingRecordsCount = unloadedRecords.length;
10725
-
10726
- if (unloadedRecords.length) {
10727
- forEach(unloadedRecords, function(record) {
10728
- this.recordArrayManager.registerWaitingRecordArray(record, manyArray);
10729
- }, this);
10730
-
10731
- resolver.resolve(this.scheduleFetchMany(unloadedRecords, owner));
10732
- } else {
10733
- if (resolver) { resolver.resolve(); }
10734
- manyArray.set('isLoaded', true);
10735
- once(manyArray, 'trigger', 'didLoad');
10736
- }
10737
-
10738
- return manyArray;
10297
+ findMany: function(records) {
10298
+ var store = this;
10299
+ return Promise.all( map(records, function(record) {
10300
+ return store._findByRecord(record);
10301
+ }));
10739
10302
  },
10740
10303
 
10304
+
10741
10305
  /**
10742
10306
  If a relationship was originally populated by the adapter as a link
10743
10307
  (as opposed to a list of IDs), this method is called when the
@@ -10756,13 +10320,11 @@ define("ember-data/system/store",
10756
10320
  @param {String or subclass of DS.Model} type
10757
10321
  @return {Promise} promise
10758
10322
  */
10759
- findHasMany: function(owner, link, relationship, resolver) {
10323
+ findHasMany: function(owner, link, type) {
10760
10324
  var adapter = this.adapterFor(owner.constructor);
10761
10325
 
10762
10326
 
10763
- var records = this.recordArrayManager.createManyArray(relationship.type, Ember.A([]));
10764
- resolver.resolve(_findHasMany(adapter, this, owner, link, relationship));
10765
- return records;
10327
+ return _findHasMany(adapter, this, owner, link, type);
10766
10328
  },
10767
10329
 
10768
10330
  /**
@@ -11102,6 +10664,7 @@ define("ember-data/system/store",
11102
10664
  if (data) {
11103
10665
  // normalize relationship IDs into records
11104
10666
  data = normalizeRelationships(this, record.constructor, data, record);
10667
+ setupRelationships(this, record, data);
11105
10668
 
11106
10669
  this.updateId(record, data);
11107
10670
  }
@@ -11222,11 +10785,11 @@ define("ember-data/system/store",
11222
10785
  var factory;
11223
10786
 
11224
10787
  if (typeof key === 'string') {
11225
- var normalizedKey = this.container.normalize('model:' + key);
11226
-
11227
- factory = this.container.lookupFactory(normalizedKey);
11228
- if (!factory) { throw new Ember.Error("No model was found for '" + key + "'"); }
11229
- factory.typeKey = this._normalizeTypeKey(normalizedKey.split(':', 2)[1]);
10788
+ factory = this.container.lookupFactory('model:' + key);
10789
+ if (!factory) {
10790
+ throw new Ember.Error("No model was found for '" + key + "'");
10791
+ }
10792
+ factory.typeKey = factory.typeKey || this._normalizeTypeKey(key);
11230
10793
  } else {
11231
10794
  // A factory already supplied. Ensure it has a normalized key.
11232
10795
  factory = key;
@@ -11304,16 +10867,28 @@ define("ember-data/system/store",
11304
10867
  // _partial is an internal param used by `update`.
11305
10868
  // If passed, it means that the data should be
11306
10869
  // merged into the existing data, not replace it.
11307
-
11308
-
10870
+
11309
10871
  var type = this.modelFor(typeName);
11310
10872
 
11311
- // normalize relationship IDs into records
10873
+ // If the payload contains relationships that are specified as
10874
+ // IDs, normalizeRelationships will convert them into DS.Model instances
10875
+ // (possibly unloaded) before we push the payload into the
10876
+ // store.
10877
+
11312
10878
  data = normalizeRelationships(this, type, data);
11313
10879
 
10880
+ // Actually load the record into the store.
10881
+
11314
10882
  this._load(type, data, _partial);
11315
10883
 
11316
- return this.recordForId(type, data.id);
10884
+ var record = this.recordForId(type, data.id);
10885
+
10886
+ // Now that the pushed record as well as any related records
10887
+ // are in the store, create the data structures used to track
10888
+ // relationships.
10889
+ setupRelationships(this, record, data);
10890
+
10891
+ return record;
11317
10892
  },
11318
10893
 
11319
10894
  /**
@@ -11446,9 +11021,14 @@ define("ember-data/system/store",
11446
11021
  @return {Array}
11447
11022
  */
11448
11023
  pushMany: function(type, datas) {
11449
- return map(datas, function(data) {
11450
- return this.push(type, data);
11451
- }, this);
11024
+ var length = datas.length;
11025
+ var result = new Array(length);
11026
+
11027
+ for (var i = 0; i < length; i++) {
11028
+ result[i] = this.push(type, datas[i]);
11029
+ }
11030
+
11031
+ return result;
11452
11032
  },
11453
11033
 
11454
11034
  /**
@@ -11531,59 +11111,6 @@ define("ember-data/system/store",
11531
11111
  typeMap.records.splice(loc, 1);
11532
11112
  },
11533
11113
 
11534
- // ........................
11535
- // . RELATIONSHIP CHANGES .
11536
- // ........................
11537
-
11538
- addRelationshipChangeFor: function(childRecord, childKey, parentRecord, parentKey, change) {
11539
- var clientId = childRecord.clientId;
11540
- var parentClientId = parentRecord ? parentRecord : parentRecord;
11541
- var key = childKey + parentKey;
11542
- var changes = this._relationshipChanges;
11543
-
11544
- if (!(clientId in changes)) {
11545
- changes[clientId] = {};
11546
- }
11547
- if (!(parentClientId in changes[clientId])) {
11548
- changes[clientId][parentClientId] = {};
11549
- }
11550
- if (!(key in changes[clientId][parentClientId])) {
11551
- changes[clientId][parentClientId][key] = {};
11552
- }
11553
- changes[clientId][parentClientId][key][change.changeType] = change;
11554
- },
11555
-
11556
- removeRelationshipChangeFor: function(clientRecord, childKey, parentRecord, parentKey, type) {
11557
- var clientId = clientRecord.clientId;
11558
- var parentClientId = parentRecord ? parentRecord.clientId : parentRecord;
11559
- var changes = this._relationshipChanges;
11560
- var key = childKey + parentKey;
11561
-
11562
- if (!(clientId in changes) || !(parentClientId in changes[clientId]) || !(key in changes[clientId][parentClientId])){
11563
- return;
11564
- }
11565
- delete changes[clientId][parentClientId][key][type];
11566
- },
11567
-
11568
- relationshipChangePairsFor: function(record){
11569
- var toReturn = [];
11570
-
11571
- if( !record ) { return toReturn; }
11572
-
11573
- //TODO(Igor) What about the other side
11574
- var changesObject = this._relationshipChanges[record.clientId];
11575
- for (var objKey in changesObject){
11576
- if (changesObject.hasOwnProperty(objKey)){
11577
- for (var changeKey in changesObject[objKey]){
11578
- if (changesObject[objKey].hasOwnProperty(changeKey)){
11579
- toReturn.push(changesObject[objKey][changeKey]);
11580
- }
11581
- }
11582
- }
11583
- }
11584
- return toReturn;
11585
- },
11586
-
11587
11114
  // ......................
11588
11115
  // . PER-TYPE ADAPTERS
11589
11116
  // ......................
@@ -11637,7 +11164,6 @@ define("ember-data/system/store",
11637
11164
  willDestroy: function() {
11638
11165
  var typeMaps = this.typeMaps;
11639
11166
  var keys = Ember.keys(typeMaps);
11640
- var store = this;
11641
11167
 
11642
11168
  var types = map(keys, byType);
11643
11169
 
@@ -11665,30 +11191,15 @@ define("ember-data/system/store",
11665
11191
  }
11666
11192
  });
11667
11193
 
11194
+
11668
11195
  function normalizeRelationships(store, type, data, record) {
11669
11196
  type.eachRelationship(function(key, relationship) {
11670
- // A link (usually a URL) was already provided in
11671
- // normalized form
11672
- if (data.links && data.links[key]) {
11673
- if (record && relationship.options.async) { record._relationships[key] = null; }
11674
- return;
11675
- }
11676
-
11677
11197
  var kind = relationship.kind;
11678
11198
  var value = data[key];
11679
-
11680
- if (value == null) {
11681
- if (kind === 'hasMany' && record) {
11682
- value = data[key] = record.get(key).toArray();
11683
- }
11684
- return;
11685
- }
11686
-
11687
11199
  if (kind === 'belongsTo') {
11688
11200
  deserializeRecordId(store, data, key, relationship, value);
11689
11201
  } else if (kind === 'hasMany') {
11690
11202
  deserializeRecordIds(store, data, key, relationship, value);
11691
- addUnsavedRecords(record, key, value);
11692
11203
  }
11693
11204
  });
11694
11205
 
@@ -11721,104 +11232,16 @@ define("ember-data/system/store",
11721
11232
  }
11722
11233
 
11723
11234
  function deserializeRecordIds(store, data, key, relationship, ids) {
11235
+ if (!Ember.isArray(ids)) {
11236
+ return;
11237
+ }
11724
11238
  for (var i=0, l=ids.length; i<l; i++) {
11725
11239
  deserializeRecordId(store, ids, i, relationship, ids[i]);
11726
11240
  }
11727
11241
  }
11728
11242
 
11729
- // If there are any unsaved records that are in a hasMany they won't be
11730
- // in the payload, so add them back in manually.
11731
- function addUnsavedRecords(record, key, data) {
11732
- if(record) {
11733
- var unsavedRecords = uniqById(Ember.A(data), record.get(key).filterBy('isNew'));
11734
- Ember.A(data).pushObjects(unsavedRecords);
11735
- }
11736
- }
11737
-
11738
- function uniqById(data, records) {
11739
- var currentIds = data.mapBy("id");
11740
- return records.reject(function(record) {
11741
- return Ember.A(currentIds).contains(record.id);
11742
- });
11743
- }
11744
-
11745
11243
  // Delegation to the adapter and promise management
11746
- /**
11747
- A `PromiseArray` is an object that acts like both an `Ember.Array`
11748
- and a promise. When the promise is resolved the resulting value
11749
- will be set to the `PromiseArray`'s `content` property. This makes
11750
- it easy to create data bindings with the `PromiseArray` that will be
11751
- updated when the promise resolves.
11752
-
11753
- For more information see the [Ember.PromiseProxyMixin
11754
- documentation](/api/classes/Ember.PromiseProxyMixin.html).
11755
-
11756
- Example
11757
-
11758
- ```javascript
11759
- var promiseArray = DS.PromiseArray.create({
11760
- promise: $.getJSON('/some/remote/data.json')
11761
- });
11762
-
11763
- promiseArray.get('length'); // 0
11764
-
11765
- promiseArray.then(function() {
11766
- promiseArray.get('length'); // 100
11767
- });
11768
- ```
11769
-
11770
- @class PromiseArray
11771
- @namespace DS
11772
- @extends Ember.ArrayProxy
11773
- @uses Ember.PromiseProxyMixin
11774
- */
11775
- PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
11776
- /**
11777
- A `PromiseObject` is an object that acts like both an `Ember.Object`
11778
- and a promise. When the promise is resolved, then the resulting value
11779
- will be set to the `PromiseObject`'s `content` property. This makes
11780
- it easy to create data bindings with the `PromiseObject` that will
11781
- be updated when the promise resolves.
11782
-
11783
- For more information see the [Ember.PromiseProxyMixin
11784
- documentation](/api/classes/Ember.PromiseProxyMixin.html).
11785
-
11786
- Example
11787
-
11788
- ```javascript
11789
- var promiseObject = DS.PromiseObject.create({
11790
- promise: $.getJSON('/some/remote/data.json')
11791
- });
11792
-
11793
- promiseObject.get('name'); // null
11794
-
11795
- promiseObject.then(function() {
11796
- promiseObject.get('name'); // 'Tomster'
11797
- });
11798
- ```
11799
-
11800
- @class PromiseObject
11801
- @namespace DS
11802
- @extends Ember.ObjectProxy
11803
- @uses Ember.PromiseProxyMixin
11804
- */
11805
- PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
11806
-
11807
- function promiseObject(promise, label) {
11808
- return PromiseObject.create({
11809
- promise: Promise.cast(promise, label)
11810
- });
11811
- }
11812
-
11813
- function promiseArray(promise, label) {
11814
- return PromiseArray.create({
11815
- promise: Promise.cast(promise, label)
11816
- });
11817
- }
11818
11244
 
11819
- function isThenable(object) {
11820
- return object && typeof object.then === 'function';
11821
- }
11822
11245
 
11823
11246
  function serializerFor(container, type, defaultSerializer) {
11824
11247
  return container.lookup('serializer:'+type) ||
@@ -11903,8 +11326,6 @@ define("ember-data/system/store",
11903
11326
  throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
11904
11327
  }
11905
11328
 
11906
- var guardedPromise;
11907
-
11908
11329
  promise = Promise.cast(promise, label);
11909
11330
  promise = _guard(promise, _bind(_objectIsAlive, store));
11910
11331
 
@@ -11930,7 +11351,7 @@ define("ember-data/system/store",
11930
11351
 
11931
11352
 
11932
11353
  var records = store.pushMany(relationship.type, payload);
11933
- record.updateHasMany(relationship.key, records);
11354
+ return records;
11934
11355
  }, null, "DS: Extract payload of " + record + " : hasMany " + relationship.type);
11935
11356
  }
11936
11357
 
@@ -11946,8 +11367,6 @@ define("ember-data/system/store",
11946
11367
  return promise.then(function(adapterPayload) {
11947
11368
  var payload = serializer.extract(store, relationship.type, adapterPayload, null, 'findBelongsTo');
11948
11369
  var record = store.push(relationship.type, payload);
11949
-
11950
- record.updateBelongsTo(relationship.key, record);
11951
11370
  return record;
11952
11371
  }, null, "DS: Extract payload of " + record + " : " + relationship.type);
11953
11372
  }
@@ -12020,10 +11439,30 @@ define("ember-data/system/store",
12020
11439
  }, label);
12021
11440
  }
12022
11441
 
12023
- __exports__.Store = Store;
12024
- __exports__.PromiseArray = PromiseArray;
12025
- __exports__.PromiseObject = PromiseObject;
11442
+ function setupRelationships(store, record, data) {
11443
+ var type = record.constructor;
11444
+
11445
+ type.eachRelationship(function(key, descriptor) {
11446
+ var kind = descriptor.kind;
11447
+ var value = data[key];
11448
+ var relationship = record._relationships[key];
12026
11449
 
11450
+ if (data.links && data.links[key]) {
11451
+ relationship.updateLink(data.links[key]);
11452
+ }
11453
+
11454
+ if (kind === 'belongsTo') {
11455
+ if (value === undefined) {
11456
+ return;
11457
+ }
11458
+ relationship.setRecord(value);
11459
+ } else if (kind === 'hasMany' && value) {
11460
+ relationship.updateRecordsFromAdapter(value);
11461
+ }
11462
+ });
11463
+ }
11464
+
11465
+ __exports__.Store = Store;
12027
11466
  __exports__["default"] = Store;
12028
11467
  });
12029
11468
  define("ember-data/transforms",