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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a48704e2c701be6be7456d067208521f2182a63
4
- data.tar.gz: 264a82a1605a51829f7c203fed1615e56802df15
3
+ metadata.gz: f48e9de804e7633cde2ee245cb9c063c804d72b1
4
+ data.tar.gz: c15a96192b9ebd3fc000f41cb44596d6e781eb26
5
5
  SHA512:
6
- metadata.gz: 8aea6e81d77b2cbe3750cdc9f6e2e1acf9413b552e124ccd5a28104036c3b2ca1b721d609a55437dc808064ca7b7d307bdd1a673a7f957758ae2ab13a945599b
7
- data.tar.gz: 59b43228d51f4eeb8dff6e9ffad468a7f8bf3a33c9c406717cc5872b34acf5cce4e34c8809da56735a66e04fe83404e5e4c4b43c6734982aff925d9caffe5799
6
+ metadata.gz: 1c362c04dfee3d2950f41d76ade8f8d9ec631d19a7f7b5eba29333d7637b2f50c7385518a1a333eb6afe9c5fd2d272fe398db04a1054a1b737c5134258643759
7
+ data.tar.gz: 0751401cf62b2d2e9d0ebc4e106aa8dbe858150facbfb28e1a8721bad1af95c3a9ffea2a554e10f7d88bedc635de9265db5587ae16a8c907e9addcf80c50940b
data/dist/ember-data.js CHANGED
@@ -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;
@@ -1072,15 +1042,16 @@ define("ember-data/adapters/fixture_adapter",
1072
1042
  var adapter = this;
1073
1043
 
1074
1044
  return new Ember.RSVP.Promise(function(resolve) {
1045
+ var value = Ember.copy(callback.call(context), true);
1075
1046
  if (get(adapter, 'simulateRemoteResponse')) {
1076
1047
  // Schedule with setTimeout
1077
1048
  Ember.run.later(function() {
1078
- resolve(callback.call(context));
1049
+ resolve(value);
1079
1050
  }, get(adapter, 'latency'));
1080
1051
  } else {
1081
1052
  // Asynchronous, but at the of the runloop with zero latency
1082
1053
  Ember.run.schedule('actions', null, function() {
1083
- resolve(callback.call(context));
1054
+ resolve(value);
1084
1055
  });
1085
1056
  }
1086
1057
  }, "DS: FixtureAdapter#simulateRemoteCall");
@@ -1095,7 +1066,8 @@ define("ember-data/adapters/rest_adapter",
1095
1066
  @module ember-data
1096
1067
  */
1097
1068
 
1098
- var Adapter = __dependency1__["default"];
1069
+ var Adapter = __dependency1__.Adapter;
1070
+ var InvalidError = __dependency1__.InvalidError;
1099
1071
  var get = Ember.get;
1100
1072
  var forEach = Ember.ArrayPolyfills.forEach;
1101
1073
 
@@ -1482,7 +1454,7 @@ define("ember-data/adapters/rest_adapter",
1482
1454
  @param {String} url
1483
1455
  @return {Promise} promise
1484
1456
  */
1485
- findHasMany: function(store, record, url) {
1457
+ findHasMany: function(store, record, url, relationship) {
1486
1458
  var host = get(this, 'host');
1487
1459
  var id = get(record, 'id');
1488
1460
  var type = record.constructor.typeKey;
@@ -1521,7 +1493,7 @@ define("ember-data/adapters/rest_adapter",
1521
1493
  @param {String} url
1522
1494
  @return {Promise} promise
1523
1495
  */
1524
- findBelongsTo: function(store, record, url) {
1496
+ findBelongsTo: function(store, record, url, relationship) {
1525
1497
  var id = get(record, 'id');
1526
1498
  var type = record.constructor.typeKey;
1527
1499
 
@@ -1812,9 +1784,10 @@ define("ember-data/adapters/rest_adapter",
1812
1784
 
1813
1785
  @method ajaxError
1814
1786
  @param {Object} jqXHR
1787
+ @param {Object} responseText
1815
1788
  @return {Object} jqXHR
1816
1789
  */
1817
- ajaxError: function(jqXHR) {
1790
+ ajaxError: function(jqXHR, responseText) {
1818
1791
  if (jqXHR && typeof jqXHR === 'object') {
1819
1792
  jqXHR.then = null;
1820
1793
  }
@@ -1822,6 +1795,32 @@ define("ember-data/adapters/rest_adapter",
1822
1795
  return jqXHR;
1823
1796
  },
1824
1797
 
1798
+ /**
1799
+ Takes an ajax response, and returns the json payload.
1800
+
1801
+ By default this hook just returns the jsonPayload passed to it.
1802
+ You might want to override it in two cases:
1803
+
1804
+ 1. Your API might return useful results in the request headers.
1805
+ If you need to access these, you can override this hook to copy them
1806
+ from jqXHR to the payload object so they can be processed in you serializer.
1807
+
1808
+
1809
+ 2. Your API might return errors as successful responses with status code
1810
+ 200 and an Errors text or object. You can return a DS.InvalidError from
1811
+ this hook and it will automatically reject the promise and put your record
1812
+ into the invald state.
1813
+
1814
+ @method ajaxError
1815
+ @param {Object} jqXHR
1816
+ @param {Object} jsonPayload
1817
+ @return {Object} jqXHR
1818
+ */
1819
+
1820
+ ajaxSuccess: function(jqXHR, jsonPayload) {
1821
+ return jsonPayload;
1822
+ },
1823
+
1825
1824
  /**
1826
1825
  Takes a URL, an HTTP method and a hash of data, and makes an
1827
1826
  HTTP request.
@@ -1852,12 +1851,17 @@ define("ember-data/adapters/rest_adapter",
1852
1851
  return new Ember.RSVP.Promise(function(resolve, reject) {
1853
1852
  var hash = adapter.ajaxOptions(url, type, options);
1854
1853
 
1855
- hash.success = function(json) {
1856
- Ember.run(null, resolve, json);
1854
+ hash.success = function(json, textStatus, jqXHR) {
1855
+ json = adapter.ajaxSuccess(jqXHR, json);
1856
+ if (json instanceof InvalidError) {
1857
+ Ember.run(null, reject, json);
1858
+ } else {
1859
+ Ember.run(null, resolve, json);
1860
+ }
1857
1861
  };
1858
1862
 
1859
1863
  hash.error = function(jqXHR, textStatus, errorThrown) {
1860
- Ember.run(null, reject, adapter.ajaxError(jqXHR));
1864
+ Ember.run(null, reject, adapter.ajaxError(jqXHR, jqXHR.responseText));
1861
1865
  };
1862
1866
 
1863
1867
  Ember.$.ajax(hash);
@@ -1925,11 +1929,11 @@ define("ember-data/core",
1925
1929
  /**
1926
1930
  @property VERSION
1927
1931
  @type String
1928
- @default '1.0.0-beta.9'
1932
+ @default '1.0.0-beta.10'
1929
1933
  @static
1930
1934
  */
1931
1935
  DS = Ember.Namespace.create({
1932
- VERSION: '1.0.0-beta.9'
1936
+ VERSION: '1.0.0-beta.10'
1933
1937
  });
1934
1938
 
1935
1939
  if (Ember.libraries) {
@@ -2200,15 +2204,13 @@ define("ember-data/serializers",
2200
2204
  __exports__.RESTSerializer = RESTSerializer;
2201
2205
  });
2202
2206
  define("ember-data/serializers/embedded_records_mixin",
2203
- ["ember-inflector","exports"],
2204
- function(__dependency1__, __exports__) {
2207
+ ["exports"],
2208
+ function(__exports__) {
2205
2209
  "use strict";
2206
2210
  var get = Ember.get;
2207
2211
  var forEach = Ember.EnumerableUtils.forEach;
2208
2212
  var camelize = Ember.String.camelize;
2209
2213
 
2210
- var pluralize = __dependency1__.pluralize;
2211
-
2212
2214
  /**
2213
2215
  ## Using Embedded Records
2214
2216
 
@@ -2227,6 +2229,11 @@ define("ember-data/serializers/embedded_records_mixin",
2227
2229
  }
2228
2230
  })
2229
2231
  ```
2232
+ Note that this use of `{embedded: 'always'}` is unrelated to
2233
+ the `{embedded: 'always'}` that is defined as an option on `DS.attr` as part of
2234
+ defining a model while working with the ActiveModelSerializer. Nevertheless,
2235
+ using `{embedded: 'always'}` as an option to DS.attr is not a valid way to setup
2236
+ embedded records.
2230
2237
 
2231
2238
  The `attrs` option for a resource `{embedded: 'always'}` is shorthand for:
2232
2239
 
@@ -2260,7 +2267,11 @@ define("ember-data/serializers/embedded_records_mixin",
2260
2267
 
2261
2268
  ### Model Relationships
2262
2269
 
2263
- Embedded records must have a model defined to be extracted and serialized.
2270
+ Embedded records must have a model defined to be extracted and serialized. Note that
2271
+ when defining any relationships on your model such as `belongsTo` and `hasMany`, you
2272
+ should not both specify `async:true` and also indicate through the serializer's
2273
+ `attrs` attribute that the related model should be embedded. If a model is
2274
+ declared embedded, then do not use `async:true`.
2264
2275
 
2265
2276
  To successfully extract and serialize embedded records the model relationships
2266
2277
  must be setup correcty See the
@@ -2272,9 +2283,9 @@ define("ember-data/serializers/embedded_records_mixin",
2272
2283
 
2273
2284
  ### Example JSON payloads, Models and Serializers
2274
2285
 
2275
- **When customizing a serializer it is imporant to grok what the cusomizations
2276
- are, please read the docs for the methods this mixin provides, in case you need
2277
- to modify to fit your specific needs.**
2286
+ **When customizing a serializer it is important to grok what the customizations
2287
+ are. Please read the docs for the methods this mixin provides, in case you need
2288
+ to modify it to fit your specific needs.**
2278
2289
 
2279
2290
  For example review the docs for each method of this mixin:
2280
2291
  * [normalize](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_normalize)
@@ -2377,7 +2388,6 @@ define("ember-data/serializers/embedded_records_mixin",
2377
2388
  */
2378
2389
  serializeBelongsTo: function(record, json, relationship) {
2379
2390
  var attr = relationship.key;
2380
- var attrs = this.get('attrs');
2381
2391
  if (this.noSerializeOptionSpecified(attr)) {
2382
2392
  this._super(record, json, relationship);
2383
2393
  return;
@@ -2487,7 +2497,6 @@ define("ember-data/serializers/embedded_records_mixin",
2487
2497
  */
2488
2498
  serializeHasMany: function(record, json, relationship) {
2489
2499
  var attr = relationship.key;
2490
- var attrs = this.get('attrs');
2491
2500
  if (this.noSerializeOptionSpecified(attr)) {
2492
2501
  this._super(record, json, relationship);
2493
2502
  return;
@@ -2562,8 +2571,6 @@ define("ember-data/serializers/embedded_records_mixin",
2562
2571
  // checks config for attrs option to serialize records
2563
2572
  noSerializeOptionSpecified: function(attr) {
2564
2573
  var option = this.attrsOption(attr);
2565
- var serializeRecords = this.hasSerializeRecordsOption(attr);
2566
- var serializeIds = this.hasSerializeIdsOption(attr);
2567
2574
  return !(option && (option.serialize || option.embedded));
2568
2575
  },
2569
2576
 
@@ -2590,7 +2597,12 @@ define("ember-data/serializers/embedded_records_mixin",
2590
2597
  if (serializer.hasDeserializeRecordsOption(key)) {
2591
2598
  var embeddedType = store.modelFor(relationship.type.typeKey);
2592
2599
  if (relationship.kind === "hasMany") {
2593
- extractEmbeddedHasMany(store, key, embeddedType, partial);
2600
+ if (relationship.options.polymorphic) {
2601
+ extractEmbeddedHasManyPolymorphic(store, key, partial);
2602
+ }
2603
+ else {
2604
+ extractEmbeddedHasMany(store, key, embeddedType, partial);
2605
+ }
2594
2606
  }
2595
2607
  if (relationship.kind === "belongsTo") {
2596
2608
  extractEmbeddedBelongsTo(store, key, embeddedType, partial);
@@ -2620,6 +2632,28 @@ define("ember-data/serializers/embedded_records_mixin",
2620
2632
  return hash;
2621
2633
  }
2622
2634
 
2635
+ function extractEmbeddedHasManyPolymorphic(store, key, hash) {
2636
+ if (!hash[key]) {
2637
+ return hash;
2638
+ }
2639
+
2640
+ var ids = [];
2641
+
2642
+ forEach(hash[key], function(data) {
2643
+ var typeKey = data.type;
2644
+ var embeddedSerializer = store.serializerFor(typeKey);
2645
+ var embeddedType = store.modelFor(typeKey);
2646
+ var primaryKey = get(embeddedSerializer, 'primaryKey');
2647
+
2648
+ var embeddedRecord = embeddedSerializer.normalize(embeddedType, data, null);
2649
+ store.push(embeddedType, embeddedRecord);
2650
+ ids.push({ id: embeddedRecord[primaryKey], type: typeKey });
2651
+ });
2652
+
2653
+ hash[key] = ids;
2654
+ return hash;
2655
+ }
2656
+
2623
2657
  function extractEmbeddedBelongsTo(store, key, embeddedType, hash) {
2624
2658
  if (!hash[key]) {
2625
2659
  return hash;
@@ -2637,12 +2671,10 @@ define("ember-data/serializers/embedded_records_mixin",
2637
2671
  __exports__["default"] = EmbeddedRecordsMixin;
2638
2672
  });
2639
2673
  define("ember-data/serializers/json_serializer",
2640
- ["ember-data/system/changes","exports"],
2641
- function(__dependency1__, __exports__) {
2674
+ ["exports"],
2675
+ function(__exports__) {
2642
2676
  "use strict";
2643
- var RelationshipChange = __dependency1__.RelationshipChange;
2644
2677
  var get = Ember.get;
2645
- var set = Ember.set;
2646
2678
  var isNone = Ember.isNone;
2647
2679
  var map = Ember.ArrayPolyfills.map;
2648
2680
  var merge = Ember.merge;
@@ -2752,7 +2784,7 @@ define("ember-data/serializers/json_serializer",
2752
2784
  @return {Object} data The transformed data object
2753
2785
  */
2754
2786
  applyTransforms: function(type, data) {
2755
- type.eachTransformedAttribute(function(key, type) {
2787
+ type.eachTransformedAttribute(function applyTransform(key, type) {
2756
2788
  if (!data.hasOwnProperty(key)) { return; }
2757
2789
 
2758
2790
  var transform = this.transformFor(type);
@@ -2838,7 +2870,7 @@ define("ember-data/serializers/json_serializer",
2838
2870
  @private
2839
2871
  */
2840
2872
  normalizeAttributes: function(type, hash) {
2841
- var payloadKey, key;
2873
+ var payloadKey;
2842
2874
 
2843
2875
  if (this.keyForAttribute) {
2844
2876
  type.eachAttribute(function(key) {
@@ -2857,7 +2889,7 @@ define("ember-data/serializers/json_serializer",
2857
2889
  @private
2858
2890
  */
2859
2891
  normalizeRelationships: function(type, hash) {
2860
- var payloadKey, key;
2892
+ var payloadKey;
2861
2893
 
2862
2894
  if (this.keyForRelationship) {
2863
2895
  type.eachRelationship(function(key, relationship) {
@@ -3276,7 +3308,7 @@ define("ember-data/serializers/json_serializer",
3276
3308
  payloadKey = this.keyForRelationship(key, "hasMany");
3277
3309
  }
3278
3310
 
3279
- var relationshipType = RelationshipChange.determineRelationshipType(record.constructor, relationship);
3311
+ var relationshipType = record.constructor.determineRelationshipType(relationship);
3280
3312
 
3281
3313
  if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') {
3282
3314
  json[payloadKey] = get(record, key).mapBy('id');
@@ -3686,7 +3718,6 @@ define("ember-data/serializers/rest_serializer",
3686
3718
 
3687
3719
  var JSONSerializer = __dependency1__["default"];
3688
3720
  var get = Ember.get;
3689
- var set = Ember.set;
3690
3721
  var forEach = Ember.ArrayPolyfills.forEach;
3691
3722
  var map = Ember.ArrayPolyfills.map;
3692
3723
  var camelize = Ember.String.camelize;
@@ -4367,7 +4398,7 @@ define("ember-data/serializers/rest_serializer",
4367
4398
 
4368
4399
  /**
4369
4400
  You can use this method to customize the root keys serialized into the JSON.
4370
- By default the REST Serializer sends the typeKey of a model, whih is a camelized
4401
+ By default the REST Serializer sends the typeKey of a model, which is a camelized
4371
4402
  version of the name.
4372
4403
 
4373
4404
  For example, your server may expect underscored root objects.
@@ -4444,8 +4475,6 @@ define("ember-data/system/adapter",
4444
4475
  */
4445
4476
 
4446
4477
  var get = Ember.get;
4447
- var set = Ember.set;
4448
- var map = Ember.ArrayPolyfills.map;
4449
4478
 
4450
4479
  var errorProps = [
4451
4480
  'description',
@@ -4902,465 +4931,6 @@ define("ember-data/system/adapter",
4902
4931
  __exports__.Adapter = Adapter;
4903
4932
  __exports__["default"] = Adapter;
4904
4933
  });
4905
- define("ember-data/system/changes",
4906
- ["ember-data/system/changes/relationship_change","exports"],
4907
- function(__dependency1__, __exports__) {
4908
- "use strict";
4909
- /**
4910
- @module ember-data
4911
- */
4912
-
4913
- var RelationshipChange = __dependency1__.RelationshipChange;
4914
- var RelationshipChangeAdd = __dependency1__.RelationshipChangeAdd;
4915
- var RelationshipChangeRemove = __dependency1__.RelationshipChangeRemove;
4916
- var OneToManyChange = __dependency1__.OneToManyChange;
4917
- var ManyToNoneChange = __dependency1__.ManyToNoneChange;
4918
- var OneToOneChange = __dependency1__.OneToOneChange;
4919
- var ManyToManyChange = __dependency1__.ManyToManyChange;
4920
-
4921
- __exports__.RelationshipChange = RelationshipChange;
4922
- __exports__.RelationshipChangeAdd = RelationshipChangeAdd;
4923
- __exports__.RelationshipChangeRemove = RelationshipChangeRemove;
4924
- __exports__.OneToManyChange = OneToManyChange;
4925
- __exports__.ManyToNoneChange = ManyToNoneChange;
4926
- __exports__.OneToOneChange = OneToOneChange;
4927
- __exports__.ManyToManyChange = ManyToManyChange;
4928
- });
4929
- define("ember-data/system/changes/relationship_change",
4930
- ["ember-data/system/model/model","ember-data/system/relationship-meta","exports"],
4931
- function(__dependency1__, __dependency2__, __exports__) {
4932
- "use strict";
4933
- /**
4934
- @module ember-data
4935
- */
4936
-
4937
- var Model = __dependency1__["default"];
4938
- var isSyncRelationship = __dependency2__.isSyncRelationship;
4939
-
4940
- var get = Ember.get;
4941
- var set = Ember.set;
4942
- var forEach = Ember.EnumerableUtils.forEach;
4943
-
4944
- /**
4945
- @class RelationshipChange
4946
- @namespace DS
4947
- @private
4948
- @constructor
4949
- */
4950
- var RelationshipChange = function(options) {
4951
- this.parentRecord = options.parentRecord;
4952
- this.childRecord = options.childRecord;
4953
- this.firstRecord = options.firstRecord;
4954
- this.firstRecordKind = options.firstRecordKind;
4955
- this.firstRecordName = options.firstRecordName;
4956
- this.secondRecord = options.secondRecord;
4957
- this.secondRecordKind = options.secondRecordKind;
4958
- this.secondRecordName = options.secondRecordName;
4959
- this.changeType = options.changeType;
4960
- this.store = options.store;
4961
-
4962
- this.committed = {};
4963
- };
4964
-
4965
- /**
4966
- @class RelationshipChangeAdd
4967
- @namespace DS
4968
- @private
4969
- @constructor
4970
- */
4971
- function RelationshipChangeAdd(options){
4972
- RelationshipChange.call(this, options);
4973
- }
4974
-
4975
- /**
4976
- @class RelationshipChangeRemove
4977
- @namespace DS
4978
- @private
4979
- @constructor
4980
- */
4981
- function RelationshipChangeRemove(options){
4982
- RelationshipChange.call(this, options);
4983
- }
4984
-
4985
- RelationshipChange.create = function(options) {
4986
- return new RelationshipChange(options);
4987
- };
4988
-
4989
- RelationshipChangeAdd.create = function(options) {
4990
- return new RelationshipChangeAdd(options);
4991
- };
4992
-
4993
- RelationshipChangeRemove.create = function(options) {
4994
- return new RelationshipChangeRemove(options);
4995
- };
4996
-
4997
- var OneToManyChange = {};
4998
- var OneToNoneChange = {};
4999
- var ManyToNoneChange = {};
5000
- var OneToOneChange = {};
5001
- var ManyToManyChange = {};
5002
-
5003
- RelationshipChange._createChange = function(options){
5004
- if (options.changeType === 'add') {
5005
- return RelationshipChangeAdd.create(options);
5006
- }
5007
- if (options.changeType === 'remove') {
5008
- return RelationshipChangeRemove.create(options);
5009
- }
5010
- };
5011
-
5012
- RelationshipChange.determineRelationshipType = function(recordType, knownSide){
5013
- var knownKey = knownSide.key, key, otherKind;
5014
- var knownKind = knownSide.kind;
5015
-
5016
- var inverse = recordType.inverseFor(knownKey);
5017
-
5018
- if (inverse) {
5019
- key = inverse.name;
5020
- otherKind = inverse.kind;
5021
- }
5022
-
5023
- if (!inverse) {
5024
- return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
5025
- } else {
5026
- if (otherKind === 'belongsTo') {
5027
- return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
5028
- } else {
5029
- return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
5030
- }
5031
- }
5032
- };
5033
-
5034
- RelationshipChange.createChange = function(firstRecord, secondRecord, store, options){
5035
- // Get the type of the child based on the child's client ID
5036
- var firstRecordType = firstRecord.constructor, changeType;
5037
- changeType = RelationshipChange.determineRelationshipType(firstRecordType, options);
5038
- if (changeType === 'oneToMany') {
5039
- return OneToManyChange.createChange(firstRecord, secondRecord, store, options);
5040
- } else if (changeType === 'manyToOne') {
5041
- return OneToManyChange.createChange(secondRecord, firstRecord, store, options);
5042
- } else if (changeType === 'oneToNone') {
5043
- return OneToNoneChange.createChange(firstRecord, secondRecord, store, options);
5044
- } else if (changeType === 'manyToNone') {
5045
- return ManyToNoneChange.createChange(firstRecord, secondRecord, store, options);
5046
- } else if (changeType === 'oneToOne') {
5047
- return OneToOneChange.createChange(firstRecord, secondRecord, store, options);
5048
- } else if (changeType === 'manyToMany') {
5049
- return ManyToManyChange.createChange(firstRecord, secondRecord, store, options);
5050
- }
5051
- };
5052
-
5053
- OneToNoneChange.createChange = function(childRecord, parentRecord, store, options) {
5054
- var key = options.key;
5055
- var change = RelationshipChange._createChange({
5056
- parentRecord: parentRecord,
5057
- childRecord: childRecord,
5058
- firstRecord: childRecord,
5059
- store: store,
5060
- changeType: options.changeType,
5061
- firstRecordName: key,
5062
- firstRecordKind: 'belongsTo'
5063
- });
5064
-
5065
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5066
-
5067
- return change;
5068
- };
5069
-
5070
- ManyToNoneChange.createChange = function(childRecord, parentRecord, store, options) {
5071
- var key = options.key;
5072
- var change = RelationshipChange._createChange({
5073
- parentRecord: childRecord,
5074
- childRecord: parentRecord,
5075
- secondRecord: childRecord,
5076
- store: store,
5077
- changeType: options.changeType,
5078
- secondRecordName: options.key,
5079
- secondRecordKind: 'hasMany'
5080
- });
5081
-
5082
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5083
- return change;
5084
- };
5085
-
5086
-
5087
- ManyToManyChange.createChange = function(childRecord, parentRecord, store, options) {
5088
- // If the name of the belongsTo side of the relationship is specified,
5089
- // use that
5090
- // If the type of the parent is specified, look it up on the child's type
5091
- // definition.
5092
- var key = options.key;
5093
-
5094
- var change = RelationshipChange._createChange({
5095
- parentRecord: parentRecord,
5096
- childRecord: childRecord,
5097
- firstRecord: childRecord,
5098
- secondRecord: parentRecord,
5099
- firstRecordKind: 'hasMany',
5100
- secondRecordKind: 'hasMany',
5101
- store: store,
5102
- changeType: options.changeType,
5103
- firstRecordName: key
5104
- });
5105
-
5106
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5107
-
5108
- return change;
5109
- };
5110
-
5111
- OneToOneChange.createChange = function(childRecord, parentRecord, store, options) {
5112
- var key;
5113
-
5114
- // If the name of the belongsTo side of the relationship is specified,
5115
- // use that
5116
- // If the type of the parent is specified, look it up on the child's type
5117
- // definition.
5118
- if (options.parentType) {
5119
- key = options.parentType.inverseFor(options.key).name;
5120
- } else if (options.key) {
5121
- key = options.key;
5122
- } else {
5123
- Ember.assert('You must pass either a parentType or belongsToName option to OneToManyChange.forChildAndParent', false);
5124
- }
5125
-
5126
- var change = RelationshipChange._createChange({
5127
- parentRecord: parentRecord,
5128
- childRecord: childRecord,
5129
- firstRecord: childRecord,
5130
- secondRecord: parentRecord,
5131
- firstRecordKind: 'belongsTo',
5132
- secondRecordKind: 'belongsTo',
5133
- store: store,
5134
- changeType: options.changeType,
5135
- firstRecordName: key
5136
- });
5137
-
5138
- store.addRelationshipChangeFor(childRecord, key, parentRecord, null, change);
5139
-
5140
- return change;
5141
- };
5142
-
5143
- OneToOneChange.maintainInvariant = function(options, store, childRecord, key){
5144
- if (options.changeType === 'add' && store.recordIsMaterialized(childRecord)) {
5145
- var oldParent = get(childRecord, key);
5146
- if (oldParent) {
5147
- var correspondingChange = OneToOneChange.createChange(childRecord, oldParent, store, {
5148
- parentType: options.parentType,
5149
- hasManyName: options.hasManyName,
5150
- changeType: 'remove',
5151
- key: options.key
5152
- });
5153
- store.addRelationshipChangeFor(childRecord, key, options.parentRecord , null, correspondingChange);
5154
- correspondingChange.sync();
5155
- }
5156
- }
5157
- };
5158
-
5159
- OneToManyChange.createChange = function(childRecord, parentRecord, store, options) {
5160
- var key;
5161
-
5162
- // If the name of the belongsTo side of the relationship is specified,
5163
- // use that
5164
- // If the type of the parent is specified, look it up on the child's type
5165
- // definition.
5166
- if (options.parentType) {
5167
- key = options.parentType.inverseFor(options.key).name;
5168
- OneToManyChange.maintainInvariant( options, store, childRecord, key );
5169
- } else if (options.key) {
5170
- key = options.key;
5171
- } else {
5172
- Ember.assert('You must pass either a parentType or belongsToName option to OneToManyChange.forChildAndParent', false);
5173
- }
5174
-
5175
- var change = RelationshipChange._createChange({
5176
- parentRecord: parentRecord,
5177
- childRecord: childRecord,
5178
- firstRecord: childRecord,
5179
- secondRecord: parentRecord,
5180
- firstRecordKind: 'belongsTo',
5181
- secondRecordKind: 'hasMany',
5182
- store: store,
5183
- changeType: options.changeType,
5184
- firstRecordName: key
5185
- });
5186
-
5187
- store.addRelationshipChangeFor(childRecord, key, parentRecord, change.getSecondRecordName(), change);
5188
-
5189
- return change;
5190
- };
5191
-
5192
- OneToManyChange.maintainInvariant = function(options, store, childRecord, key){
5193
- if (options.changeType === 'add' && childRecord) {
5194
- var oldParent = get(childRecord, key);
5195
- if (oldParent) {
5196
- var correspondingChange = OneToManyChange.createChange(childRecord, oldParent, store, {
5197
- parentType: options.parentType,
5198
- hasManyName: options.hasManyName,
5199
- changeType: 'remove',
5200
- key: options.key
5201
- });
5202
- store.addRelationshipChangeFor(childRecord, key, options.parentRecord, correspondingChange.getSecondRecordName(), correspondingChange);
5203
- correspondingChange.sync();
5204
- }
5205
- }
5206
- };
5207
-
5208
- /**
5209
- @class RelationshipChange
5210
- @namespace DS
5211
- */
5212
- RelationshipChange.prototype = {
5213
- getSecondRecordName: function() {
5214
- var name = this.secondRecordName, parent;
5215
-
5216
- if (!name) {
5217
- parent = this.secondRecord;
5218
- if (!parent) { return; }
5219
-
5220
- var childType = this.firstRecord.constructor;
5221
- var inverse = childType.inverseFor(this.firstRecordName);
5222
- this.secondRecordName = inverse.name;
5223
- }
5224
-
5225
- return this.secondRecordName;
5226
- },
5227
-
5228
- /**
5229
- Get the name of the relationship on the belongsTo side.
5230
-
5231
- @method getFirstRecordName
5232
- @return {String}
5233
- */
5234
- getFirstRecordName: function() {
5235
- return this.firstRecordName;
5236
- },
5237
-
5238
- /**
5239
- @method destroy
5240
- @private
5241
- */
5242
- destroy: function() {
5243
- var childRecord = this.childRecord;
5244
- var belongsToName = this.getFirstRecordName();
5245
- var hasManyName = this.getSecondRecordName();
5246
- var store = this.store;
5247
-
5248
- store.removeRelationshipChangeFor(childRecord, belongsToName, this.parentRecord, hasManyName, this.changeType);
5249
- },
5250
-
5251
- getSecondRecord: function(){
5252
- return this.secondRecord;
5253
- },
5254
-
5255
- /**
5256
- @method getFirstRecord
5257
- @private
5258
- */
5259
- getFirstRecord: function() {
5260
- return this.firstRecord;
5261
- },
5262
-
5263
- coalesce: function(){
5264
- var relationshipPairs = this.store.relationshipChangePairsFor(this.firstRecord);
5265
- forEach(relationshipPairs, function(pair) {
5266
- var addedChange = pair['add'];
5267
- var removedChange = pair['remove'];
5268
- if (addedChange && removedChange) {
5269
- addedChange.destroy();
5270
- removedChange.destroy();
5271
- }
5272
- });
5273
- }
5274
- };
5275
-
5276
- RelationshipChangeAdd.prototype = Ember.create(RelationshipChange.create({}));
5277
- RelationshipChangeRemove.prototype = Ember.create(RelationshipChange.create({}));
5278
-
5279
- RelationshipChangeAdd.prototype.changeType = 'add';
5280
- RelationshipChangeAdd.prototype.sync = function() {
5281
- var secondRecordName = this.getSecondRecordName();
5282
- var firstRecordName = this.getFirstRecordName();
5283
- var firstRecord = this.getFirstRecord();
5284
- var secondRecord = this.getSecondRecord();
5285
-
5286
- //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);
5287
- //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);
5288
-
5289
- if (secondRecord instanceof Model && firstRecord instanceof Model) {
5290
- if (this.secondRecordKind === 'belongsTo') {
5291
- secondRecord.suspendRelationshipObservers(function() {
5292
- set(secondRecord, secondRecordName, firstRecord);
5293
- });
5294
- } else if (this.secondRecordKind === 'hasMany' && isSyncRelationship(secondRecord, secondRecordName)) {
5295
- secondRecord.suspendRelationshipObservers(function() {
5296
- var relationship = get(secondRecord, secondRecordName);
5297
- relationship.addObject(firstRecord);
5298
- });
5299
- }
5300
- }
5301
-
5302
- if (firstRecord instanceof Model && secondRecord instanceof Model && get(firstRecord, firstRecordName) !== secondRecord) {
5303
- if (this.firstRecordKind === 'belongsTo') {
5304
- firstRecord.suspendRelationshipObservers(function() {
5305
- set(firstRecord, firstRecordName, secondRecord);
5306
- });
5307
- } else if (this.firstRecordKind === 'hasMany' && isSyncRelationship(secondRecord, secondRecordName)) {
5308
- firstRecord.suspendRelationshipObservers(function() {
5309
- var relationship = get(firstRecord, firstRecordName);
5310
- relationship.addObject(secondRecord);
5311
- });
5312
- }
5313
- }
5314
- this.coalesce();
5315
- };
5316
-
5317
- RelationshipChangeRemove.prototype.changeType = 'remove';
5318
- RelationshipChangeRemove.prototype.sync = function() {
5319
- var secondRecordName = this.getSecondRecordName();
5320
- var firstRecordName = this.getFirstRecordName();
5321
- var firstRecord = this.getFirstRecord();
5322
- var secondRecord = this.getSecondRecord();
5323
-
5324
- //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);
5325
- //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);
5326
-
5327
- if (secondRecord instanceof Model && firstRecord instanceof Model) {
5328
- if (this.secondRecordKind === 'belongsTo') {
5329
- secondRecord.suspendRelationshipObservers(function() {
5330
- set(secondRecord, secondRecordName, null);
5331
- });
5332
- } else if (this.secondRecordKind === 'hasMany' && isSyncRelationship(secondRecord, secondRecordName)) {
5333
- secondRecord.suspendRelationshipObservers(function() {
5334
- var relationship = get(secondRecord, secondRecordName);
5335
- relationship.removeObject(firstRecord);
5336
- });
5337
- }
5338
- }
5339
-
5340
- if (firstRecord instanceof Model && get(firstRecord, firstRecordName)) {
5341
- if (this.firstRecordKind === 'belongsTo') {
5342
- firstRecord.suspendRelationshipObservers(function() {
5343
- set(firstRecord, firstRecordName, null);
5344
- });
5345
- } else if (this.firstRecordKind === 'hasMany' && isSyncRelationship(firstRecord, firstRecordName)) {
5346
- firstRecord.suspendRelationshipObservers(function() {
5347
- var relationship = get(firstRecord, firstRecordName);
5348
- relationship.removeObject(secondRecord);
5349
- });
5350
- }
5351
- }
5352
-
5353
- this.coalesce();
5354
- };
5355
-
5356
- __exports__.RelationshipChange = RelationshipChange;
5357
- __exports__.RelationshipChangeAdd = RelationshipChangeAdd;
5358
- __exports__.RelationshipChangeRemove = RelationshipChangeRemove;
5359
- __exports__.OneToManyChange = OneToManyChange;
5360
- __exports__.ManyToNoneChange = ManyToNoneChange;
5361
- __exports__.OneToOneChange = OneToOneChange;
5362
- __exports__.ManyToManyChange = ManyToManyChange;
5363
- });
5364
4934
  define("ember-data/system/container_proxy",
5365
4935
  ["exports"],
5366
4936
  function(__exports__) {
@@ -5403,7 +4973,7 @@ define("ember-data/system/container_proxy",
5403
4973
  };
5404
4974
 
5405
4975
  ContainerProxy.prototype.registerDeprecations = function(proxyPairs) {
5406
- var i, proxyPair, deprecated, valid, proxy;
4976
+ var i, proxyPair, deprecated, valid;
5407
4977
 
5408
4978
  for (i = proxyPairs.length; i > 0; i--) {
5409
4979
  proxyPair = proxyPairs[i - 1];
@@ -6299,12 +5869,14 @@ define("ember-data/system/model/errors",
6299
5869
  });
6300
5870
  });
6301
5871
  define("ember-data/system/model/model",
6302
- ["ember-data/system/model/states","ember-data/system/model/errors","ember-data/system/store","exports"],
6303
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
5872
+ ["ember-data/system/model/states","ember-data/system/model/errors","ember-data/system/promise_proxies","ember-data/system/relationships/relationship","exports"],
5873
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
6304
5874
  "use strict";
6305
5875
  var RootState = __dependency1__["default"];
6306
5876
  var Errors = __dependency2__["default"];
6307
5877
  var PromiseObject = __dependency3__.PromiseObject;
5878
+ var createRelationshipFor = __dependency4__.createRelationshipFor;
5879
+
6308
5880
  /**
6309
5881
  @module ember-data
6310
5882
  */
@@ -6314,6 +5886,7 @@ define("ember-data/system/model/model",
6314
5886
  var merge = Ember.merge;
6315
5887
  var Promise = Ember.RSVP.Promise;
6316
5888
  var forEach = Ember.ArrayPolyfills.forEach;
5889
+ var map = Ember.ArrayPolyfills.map;
6317
5890
 
6318
5891
  var JSONSerializer;
6319
5892
  var retrieveFromCurrentState = Ember.computed('currentState', function(key, value) {
@@ -6746,6 +6319,12 @@ define("ember-data/system/model/model",
6746
6319
  this._attributes = {};
6747
6320
  this._inFlightAttributes = {};
6748
6321
  this._relationships = {};
6322
+ var model = this;
6323
+ //TODO Move into a getter for better perf
6324
+ this.constructor.eachRelationship(function(key, descriptor) {
6325
+ model._relationships[key] = createRelationshipFor(model, descriptor, model.store);
6326
+ });
6327
+
6749
6328
  },
6750
6329
 
6751
6330
  /**
@@ -6928,13 +6507,11 @@ define("ember-data/system/model/model",
6928
6507
  */
6929
6508
  clearRelationships: function() {
6930
6509
  this.eachRelationship(function(name, relationship) {
6931
- if (relationship.kind === 'belongsTo') {
6932
- set(this, name, null);
6933
- } else if (relationship.kind === 'hasMany') {
6934
- var hasMany = this._relationships[name];
6935
- if (hasMany) { // relationships are created lazily
6936
- hasMany.destroy();
6937
- }
6510
+ var rel = this._relationships[name];
6511
+ if (rel){
6512
+ //TODO(Igor) figure out whether we want to clear or disconnect
6513
+ rel.clear();
6514
+ rel.destroy();
6938
6515
  }
6939
6516
  }, this);
6940
6517
  },
@@ -6949,9 +6526,9 @@ define("ember-data/system/model/model",
6949
6526
  },
6950
6527
 
6951
6528
  /**
6952
- When a find request is triggered on the store, the user can optionally passed in
6529
+ When a find request is triggered on the store, the user can optionally pass in
6953
6530
  attributes and relationships to be preloaded. These are meant to behave as if they
6954
- came back from the server, expect the user obtained them out of band and is informing
6531
+ came back from the server, except the user obtained them out of band and is informing
6955
6532
  the store of their existence. The most common use case is for supporting client side
6956
6533
  nested URLs, such as `/posts/1/comments/2` so the user can do
6957
6534
  `store.find('comment', 2, {post:1})` without having to fetch the post.
@@ -6991,15 +6568,20 @@ define("ember-data/system/model/model",
6991
6568
  Ember.assert("You need to pass in an array to set a hasMany property on a record", Ember.isArray(preloadValue));
6992
6569
  var record = this;
6993
6570
 
6994
- forEach.call(preloadValue, function(recordToPush) {
6995
- recordToPush = record._convertStringOrNumberIntoRecord(recordToPush, type);
6996
- get(record, key).pushObject(recordToPush);
6571
+ var recordsToSet = map.call(preloadValue, function(recordToPush) {
6572
+ return record._convertStringOrNumberIntoRecord(recordToPush, type);
6997
6573
  });
6574
+ //We use the pathway of setting the hasMany as if it came from the adapter
6575
+ //because the user told us that they know this relationships exists already
6576
+ this._relationships[key].updateRecordsFromAdapter(recordsToSet);
6998
6577
  },
6999
6578
 
7000
6579
  _preloadBelongsTo: function(key, preloadValue, type){
7001
- var recordToPush = this._convertStringOrNumberIntoRecord(preloadValue, type);
7002
- set(this, key, recordToPush);
6580
+ var recordToSet = this._convertStringOrNumberIntoRecord(preloadValue, type);
6581
+
6582
+ //We use the pathway of setting the hasMany as if it came from the adapter
6583
+ //because the user told us that they know this relationships exists already
6584
+ this._relationships[key].setRecord(recordToSet);
7003
6585
  },
7004
6586
 
7005
6587
  _convertStringOrNumberIntoRecord: function(value, type) {
@@ -7074,9 +6656,7 @@ define("ember-data/system/model/model",
7074
6656
 
7075
6657
  if (!data) { return; }
7076
6658
 
7077
- this.suspendRelationshipObservers(function() {
7078
- this.notifyPropertyChange('data');
7079
- });
6659
+ this.notifyPropertyChange('data');
7080
6660
  },
7081
6661
 
7082
6662
  /**
@@ -7088,32 +6668,6 @@ define("ember-data/system/model/model",
7088
6668
  this.updateRecordArraysLater();
7089
6669
  },
7090
6670
 
7091
- dataDidChange: Ember.observer(function() {
7092
- this.reloadHasManys();
7093
- }, 'data'),
7094
-
7095
- reloadHasManys: function() {
7096
- var relationships = get(this.constructor, 'relationshipsByName');
7097
- this.updateRecordArraysLater();
7098
- relationships.forEach(function(name, relationship) {
7099
- if (this._data.links && this._data.links[name]) { return; }
7100
- if (relationship.kind === 'hasMany') {
7101
- this.hasManyDidChange(relationship.key);
7102
- }
7103
- }, this);
7104
- },
7105
-
7106
- hasManyDidChange: function(key) {
7107
- var hasMany = this._relationships[key];
7108
-
7109
- if (hasMany) {
7110
- var records = this._data[key] || [];
7111
-
7112
- set(hasMany, 'content', Ember.A(records));
7113
- set(hasMany, 'isLoaded', true);
7114
- hasMany.trigger('didLoad');
7115
- }
7116
- },
7117
6671
 
7118
6672
  /**
7119
6673
  @method updateRecordArraysLater
@@ -7141,18 +6695,9 @@ define("ember-data/system/model/model",
7141
6695
  this._data = data;
7142
6696
  }
7143
6697
 
7144
- var relationships = this._relationships;
7145
-
7146
- this.eachRelationship(function(name, rel) {
7147
- if (data.links && data.links[name]) { return; }
7148
- if (rel.options.async) { relationships[name] = null; }
7149
- });
7150
-
7151
6698
  if (data) { this.pushedData(); }
7152
6699
 
7153
- this.suspendRelationshipObservers(function() {
7154
- this.notifyPropertyChange('data');
7155
- });
6700
+ this.notifyPropertyChange('data');
7156
6701
  },
7157
6702
 
7158
6703
  materializeId: function(id) {
@@ -7168,27 +6713,6 @@ define("ember-data/system/model/model",
7168
6713
  this._data[name] = value;
7169
6714
  },
7170
6715
 
7171
- /**
7172
- @method updateHasMany
7173
- @private
7174
- @param {String} name
7175
- @param {Array} records
7176
- */
7177
- updateHasMany: function(name, records) {
7178
- this._data[name] = records;
7179
- this.hasManyDidChange(name);
7180
- },
7181
-
7182
- /**
7183
- @method updateBelongsTo
7184
- @private
7185
- @param {String} name
7186
- @param {DS.Model} record
7187
- */
7188
- updateBelongsTo: function(name, record) {
7189
- this._data[name] = record;
7190
- },
7191
-
7192
6716
  /**
7193
6717
  If the model `isDirty` this function will discard any unsaved
7194
6718
  changes
@@ -7219,48 +6743,13 @@ define("ember-data/system/model/model",
7219
6743
 
7220
6744
  this.send('rolledBack');
7221
6745
 
7222
- this.suspendRelationshipObservers(function() {
7223
- this.notifyPropertyChange('data');
7224
- });
6746
+ this.notifyPropertyChange('data');
7225
6747
  },
7226
6748
 
7227
6749
  toStringExtension: function() {
7228
6750
  return get(this, 'id');
7229
6751
  },
7230
6752
 
7231
- /**
7232
- The goal of this method is to temporarily disable specific observers
7233
- that take action in response to application changes.
7234
-
7235
- This allows the system to make changes (such as materialization and
7236
- rollback) that should not trigger secondary behavior (such as setting an
7237
- inverse relationship or marking records as dirty).
7238
-
7239
- The specific implementation will likely change as Ember proper provides
7240
- better infrastructure for suspending groups of observers, and if Array
7241
- observation becomes more unified with regular observers.
7242
-
7243
- @method suspendRelationshipObservers
7244
- @private
7245
- @param callback
7246
- @param binding
7247
- */
7248
- suspendRelationshipObservers: function(callback, binding) {
7249
- var observers = get(this.constructor, 'relationshipNames').belongsTo;
7250
- var self = this;
7251
-
7252
- try {
7253
- this._suspendedRelationships = true;
7254
- Ember._suspendObservers(self, observers, null, 'belongsToDidChange', function() {
7255
- Ember._suspendBeforeObservers(self, observers, null, 'belongsToWillChange', function() {
7256
- callback.call(binding || self);
7257
- });
7258
- });
7259
- } finally {
7260
- this._suspendedRelationships = false;
7261
- }
7262
- },
7263
-
7264
6753
  /**
7265
6754
  Save the record and persist any changes to the record to an
7266
6755
  extenal source via the adapter.
@@ -7627,18 +7116,6 @@ define("ember-data/system/model/states",
7627
7116
  @class RootState
7628
7117
  */
7629
7118
 
7630
- function hasDefinedProperties(object) {
7631
- // Ignore internal property defined by simulated `Ember.create`.
7632
- var names = Ember.keys(object);
7633
- var i, l, name;
7634
- for (i = 0, l = names.length; i < l; i++ ) {
7635
- name = names[i];
7636
- if (object.hasOwnProperty(name) && object[name]) { return true; }
7637
- }
7638
-
7639
- return false;
7640
- }
7641
-
7642
7119
  function didSetProperty(record, context) {
7643
7120
  if (context.value === context.originalValue) {
7644
7121
  delete record._attributes[context.name];
@@ -7713,12 +7190,8 @@ define("ember-data/system/model/states",
7713
7190
  loadingData: Ember.K,
7714
7191
 
7715
7192
  propertyWasReset: function(record, name) {
7716
- var stillDirty = false;
7717
-
7718
- for (var prop in record._attributes) {
7719
- stillDirty = true;
7720
- break;
7721
- }
7193
+ var length = Ember.keys(record._attributes);
7194
+ var stillDirty = length > 0;
7722
7195
 
7723
7196
  if (!stillDirty) { record.send('rolledBack'); }
7724
7197
  },
@@ -7943,10 +7416,7 @@ define("ember-data/system/model/states",
7943
7416
 
7944
7417
  loadedData: function(record) {
7945
7418
  record.transitionTo('loaded.created.uncommitted');
7946
-
7947
- record.suspendRelationshipObservers(function() {
7948
- record.notifyPropertyChange('data');
7949
- });
7419
+ record.notifyPropertyChange('data');
7950
7420
  },
7951
7421
 
7952
7422
  pushedData: function(record) {
@@ -8190,6 +7660,91 @@ define("ember-data/system/model/states",
8190
7660
 
8191
7661
  __exports__["default"] = RootState;
8192
7662
  });
7663
+ define("ember-data/system/promise_proxies",
7664
+ ["exports"],
7665
+ function(__exports__) {
7666
+ "use strict";
7667
+ var Promise = Ember.RSVP.Promise;
7668
+
7669
+ /**
7670
+ A `PromiseArray` is an object that acts like both an `Ember.Array`
7671
+ and a promise. When the promise is resolved the resulting value
7672
+ will be set to the `PromiseArray`'s `content` property. This makes
7673
+ it easy to create data bindings with the `PromiseArray` that will be
7674
+ updated when the promise resolves.
7675
+
7676
+ For more information see the [Ember.PromiseProxyMixin
7677
+ documentation](/api/classes/Ember.PromiseProxyMixin.html).
7678
+
7679
+ Example
7680
+
7681
+ ```javascript
7682
+ var promiseArray = DS.PromiseArray.create({
7683
+ promise: $.getJSON('/some/remote/data.json')
7684
+ });
7685
+
7686
+ promiseArray.get('length'); // 0
7687
+
7688
+ promiseArray.then(function() {
7689
+ promiseArray.get('length'); // 100
7690
+ });
7691
+ ```
7692
+
7693
+ @class PromiseArray
7694
+ @namespace DS
7695
+ @extends Ember.ArrayProxy
7696
+ @uses Ember.PromiseProxyMixin
7697
+ */
7698
+ var PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
7699
+
7700
+ /**
7701
+ A `PromiseObject` is an object that acts like both an `Ember.Object`
7702
+ and a promise. When the promise is resolved, then the resulting value
7703
+ will be set to the `PromiseObject`'s `content` property. This makes
7704
+ it easy to create data bindings with the `PromiseObject` that will
7705
+ be updated when the promise resolves.
7706
+
7707
+ For more information see the [Ember.PromiseProxyMixin
7708
+ documentation](/api/classes/Ember.PromiseProxyMixin.html).
7709
+
7710
+ Example
7711
+
7712
+ ```javascript
7713
+ var promiseObject = DS.PromiseObject.create({
7714
+ promise: $.getJSON('/some/remote/data.json')
7715
+ });
7716
+
7717
+ promiseObject.get('name'); // null
7718
+
7719
+ promiseObject.then(function() {
7720
+ promiseObject.get('name'); // 'Tomster'
7721
+ });
7722
+ ```
7723
+
7724
+ @class PromiseObject
7725
+ @namespace DS
7726
+ @extends Ember.ObjectProxy
7727
+ @uses Ember.PromiseProxyMixin
7728
+ */
7729
+ var PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
7730
+
7731
+ var promiseObject = function(promise, label) {
7732
+ return PromiseObject.create({
7733
+ promise: Promise.resolve(promise, label)
7734
+ });
7735
+ };
7736
+
7737
+ var promiseArray = function(promise, label) {
7738
+ return PromiseArray.create({
7739
+ promise: Promise.resolve(promise, label)
7740
+ });
7741
+ };
7742
+
7743
+ __exports__.PromiseArray = PromiseArray;
7744
+ __exports__.PromiseObject = PromiseObject;
7745
+ __exports__.promiseArray = promiseArray;
7746
+ __exports__.promiseObject = promiseObject;
7747
+ });
8193
7748
  define("ember-data/system/record_array_manager",
8194
7749
  ["ember-data/system/record_arrays","exports"],
8195
7750
  function(__dependency1__, __exports__) {
@@ -8203,7 +7758,6 @@ define("ember-data/system/record_array_manager",
8203
7758
  var AdapterPopulatedRecordArray = __dependency1__.AdapterPopulatedRecordArray;
8204
7759
  var ManyArray = __dependency1__.ManyArray;
8205
7760
  var get = Ember.get;
8206
- var set = Ember.set;
8207
7761
  var forEach = Ember.EnumerableUtils.forEach;
8208
7762
 
8209
7763
  /**
@@ -8528,7 +8082,6 @@ define("ember-data/system/record_arrays/adapter_populated_record_array",
8528
8082
  */
8529
8083
 
8530
8084
  var get = Ember.get;
8531
- var set = Ember.set;
8532
8085
 
8533
8086
  function cloneNull(source) {
8534
8087
  var clone = Object.create(null);
@@ -8654,22 +8207,16 @@ define("ember-data/system/record_arrays/filtered_record_array",
8654
8207
  });
8655
8208
  });
8656
8209
  define("ember-data/system/record_arrays/many_array",
8657
- ["ember-data/system/record_arrays/record_array","ember-data/system/changes","exports"],
8658
- function(__dependency1__, __dependency2__, __exports__) {
8210
+ ["ember-data/system/record_arrays/record_array","exports"],
8211
+ function(__dependency1__, __exports__) {
8659
8212
  "use strict";
8660
8213
  var RecordArray = __dependency1__["default"];
8661
- var RelationshipChange = __dependency2__.RelationshipChange;
8662
8214
 
8663
8215
  /**
8664
8216
  @module ember-data
8665
8217
  */
8666
8218
 
8667
8219
  var get = Ember.get, set = Ember.set;
8668
- var map = Ember.EnumerableUtils.map;
8669
-
8670
- function sync(change) {
8671
- change.sync();
8672
- }
8673
8220
 
8674
8221
  /**
8675
8222
  A `ManyArray` is a `RecordArray` that represents the contents of a has-many
@@ -8710,7 +8257,6 @@ define("ember-data/system/record_arrays/many_array",
8710
8257
  __exports__["default"] = RecordArray.extend({
8711
8258
  init: function() {
8712
8259
  this._super.apply(this, arguments);
8713
- this._changesToSync = Ember.OrderedSet.create();
8714
8260
  },
8715
8261
 
8716
8262
  /**
@@ -8741,6 +8287,16 @@ define("ember-data/system/record_arrays/many_array",
8741
8287
 
8742
8288
  isLoaded: false,
8743
8289
 
8290
+ /**
8291
+ The relationship which manages this array.
8292
+
8293
+ @property {DS.Model} owner
8294
+ @private
8295
+ */
8296
+
8297
+ relationship: null,
8298
+
8299
+
8744
8300
  /**
8745
8301
  Used for async `hasMany` arrays
8746
8302
  to keep track of when they will resolve.
@@ -8771,99 +8327,14 @@ define("ember-data/system/record_arrays/many_array",
8771
8327
  }
8772
8328
  },
8773
8329
 
8774
- /**
8775
- @method fetch
8776
- @private
8777
- */
8778
- fetch: function() {
8779
- var records = get(this, 'content');
8780
- var store = get(this, 'store');
8781
- var owner = get(this, 'owner');
8782
-
8783
- var unloadedRecords = records.filterBy('isEmpty', true);
8784
- store.scheduleFetchMany(unloadedRecords, owner);
8785
- },
8786
-
8787
- // Overrides Ember.Array's replace method to implement
8788
- replaceContent: function(index, removed, added) {
8789
- // Map the array of record objects into an array of client ids.
8790
- added = map(added, function(record) {
8791
- Ember.assert("You cannot add '" + record.constructor.typeKey + "' records to this relationship (only '" + this.type.typeKey + "' allowed)", !this.type || record instanceof this.type);
8792
- return record;
8793
- }, this);
8794
-
8795
- this._super(index, removed, added);
8796
- },
8797
-
8798
- arrangedContentDidChange: function() {
8799
- Ember.run.once(this, 'fetch');
8800
- },
8801
-
8802
- arrayContentWillChange: function(index, removed, added) {
8803
- var owner = get(this, 'owner');
8804
- var name = get(this, 'name');
8805
-
8806
- if (!owner._suspendedRelationships) {
8807
- // This code is the first half of code that continues inside
8808
- // of arrayContentDidChange. It gets or creates a change from
8809
- // the child object, adds the current owner as the old
8810
- // parent if this is the first time the object was removed
8811
- // from a ManyArray, and sets `newParent` to null.
8812
- //
8813
- // Later, if the object is added to another ManyArray,
8814
- // the `arrayContentDidChange` will set `newParent` on
8815
- // the change.
8816
- for (var i=index; i<index+removed; i++) {
8817
- var record = get(this, 'content').objectAt(i);
8818
-
8819
- var change = RelationshipChange.createChange(owner, record, get(this, 'store'), {
8820
- parentType: owner.constructor,
8821
- changeType: "remove",
8822
- kind: "hasMany",
8823
- key: name
8824
- });
8825
-
8826
- this._changesToSync.add(change);
8827
- }
8330
+ replaceContent: function(idx, amt, objects){
8331
+ var records;
8332
+ if (amt > 0){
8333
+ records = get(this, 'content').slice(idx, idx+amt);
8334
+ this.get('relationship').removeRecords(records);
8828
8335
  }
8829
-
8830
- return this._super.apply(this, arguments);
8831
- },
8832
-
8833
- arrayContentDidChange: function(index, removed, added) {
8834
- this._super.apply(this, arguments);
8835
-
8836
- var owner = get(this, 'owner');
8837
- var name = get(this, 'name');
8838
- var store = get(this, 'store');
8839
-
8840
- if (!owner._suspendedRelationships) {
8841
- // This code is the second half of code that started in
8842
- // `arrayContentWillChange`. It gets or creates a change
8843
- // from the child object, and adds the current owner as
8844
- // the new parent.
8845
- for (var i=index; i<index+added; i++) {
8846
- var record = get(this, 'content').objectAt(i);
8847
-
8848
- var change = RelationshipChange.createChange(owner, record, store, {
8849
- parentType: owner.constructor,
8850
- changeType: "add",
8851
- kind:"hasMany",
8852
- key: name
8853
- });
8854
- change.hasManyName = name;
8855
-
8856
- this._changesToSync.add(change);
8857
- }
8858
-
8859
- // We wait until the array has finished being
8860
- // mutated before syncing the OneToManyChanges created
8861
- // in arrayContentWillChange, so that the array
8862
- // membership test in the sync() logic operates
8863
- // on the final results.
8864
- this._changesToSync.forEach(sync);
8865
-
8866
- this._changesToSync.clear();
8336
+ if (objects){
8337
+ this.get('relationship').addRecords(objects, idx);
8867
8338
  }
8868
8339
  },
8869
8340
 
@@ -8876,8 +8347,7 @@ define("ember-data/system/record_arrays/many_array",
8876
8347
  @return {DS.Model} record
8877
8348
  */
8878
8349
  createRecord: function(hash) {
8879
- var owner = get(this, 'owner');
8880
- var store = get(owner, 'store');
8350
+ var store = get(this, 'store');
8881
8351
  var type = get(this, 'type');
8882
8352
  var record;
8883
8353
 
@@ -8891,7 +8361,7 @@ define("ember-data/system/record_arrays/many_array",
8891
8361
  });
8892
8362
  });
8893
8363
  define("ember-data/system/record_arrays/record_array",
8894
- ["ember-data/system/store","exports"],
8364
+ ["ember-data/system/promise_proxies","exports"],
8895
8365
  function(__dependency1__, __exports__) {
8896
8366
  "use strict";
8897
8367
  /**
@@ -8900,7 +8370,6 @@ define("ember-data/system/record_arrays/record_array",
8900
8370
 
8901
8371
  var PromiseArray = __dependency1__.PromiseArray;
8902
8372
  var get = Ember.get;
8903
- var set = Ember.set;
8904
8373
 
8905
8374
  /**
8906
8375
  A record array is an array that contains records of a certain type. The record
@@ -9020,9 +8489,17 @@ define("ember-data/system/record_arrays/record_array",
9020
8489
  @method addRecord
9021
8490
  @private
9022
8491
  @param {DS.Model} record
8492
+ @param {DS.Model} an optional index to insert at
9023
8493
  */
9024
- addRecord: function(record) {
9025
- get(this, 'content').addObject(record);
8494
+ addRecord: function(record, idx) {
8495
+ var content = get(this, 'content');
8496
+ if (idx === undefined) {
8497
+ content.addObject(record);
8498
+ } else {
8499
+ if (!content.contains(record)) {
8500
+ content.insertAt(idx, record);
8501
+ }
8502
+ }
9026
8503
  },
9027
8504
 
9028
8505
  /**
@@ -9124,14 +8601,7 @@ define("ember-data/system/relationship-meta",
9124
8601
  };
9125
8602
  }
9126
8603
 
9127
- __exports__.relationshipFromMeta = relationshipFromMeta;function isSyncRelationship(record, relationshipName) {
9128
- var meta = Ember.meta(record);
9129
- var desc = meta.descs[relationshipName];
9130
-
9131
- return desc && !desc._meta.options.async;
9132
- }
9133
-
9134
- __exports__.isSyncRelationship = isSyncRelationship;
8604
+ __exports__.relationshipFromMeta = relationshipFromMeta;
9135
8605
  });
9136
8606
  define("ember-data/system/relationships",
9137
8607
  ["./relationships/belongs_to","./relationships/has_many","ember-data/system/relationships/ext","exports"],
@@ -9149,65 +8619,11 @@ define("ember-data/system/relationships",
9149
8619
  __exports__.hasMany = hasMany;
9150
8620
  });
9151
8621
  define("ember-data/system/relationships/belongs_to",
9152
- ["ember-data/system/model","ember-data/system/store","ember-data/system/changes","ember-data/system/relationship-meta","exports"],
9153
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
8622
+ ["ember-data/system/model","exports"],
8623
+ function(__dependency1__, __exports__) {
9154
8624
  "use strict";
9155
- var get = Ember.get;
9156
- var set = Ember.set;
9157
- var isNone = Ember.isNone;
9158
- var Promise = Ember.RSVP.Promise;
9159
-
9160
8625
  var Model = __dependency1__.Model;
9161
- var PromiseObject = __dependency2__.PromiseObject;
9162
- var RelationshipChange = __dependency3__.RelationshipChange;
9163
- var relationshipFromMeta = __dependency4__.relationshipFromMeta;
9164
- var typeForRelationshipMeta = __dependency4__.typeForRelationshipMeta;
9165
- var isSyncRelationship = __dependency4__.isSyncRelationship;
9166
8626
 
9167
- /**
9168
- @module ember-data
9169
- */
9170
-
9171
- function asyncBelongsTo(type, options, meta) {
9172
- return Ember.computed('data', function(key, value) {
9173
- var data = get(this, 'data');
9174
- var store = get(this, 'store');
9175
- var promiseLabel = "DS: Async belongsTo " + this + " : " + key;
9176
- var promise;
9177
-
9178
- meta.key = key;
9179
-
9180
- if (arguments.length === 2) {
9181
- Ember.assert("You can only add a '" + type + "' record to this relationship", !value || value instanceof typeForRelationshipMeta(store, meta));
9182
- return value === undefined ? null : PromiseObject.create({
9183
- promise: Promise.cast(value, promiseLabel)
9184
- });
9185
- }
9186
-
9187
- var link = data.links && data.links[key];
9188
- var belongsTo = data[key];
9189
-
9190
- if (!isNone(belongsTo)) {
9191
- var inverse = this.constructor.inverseFor(key);
9192
- //but for now only in the oneToOne case
9193
- if (inverse && inverse.kind === 'belongsTo'){
9194
- set(belongsTo, inverse.name, this);
9195
- }
9196
- //TODO(Igor) after OR doesn't seem that will be called
9197
- promise = store.findById(belongsTo.constructor, belongsTo.get('id')) || Promise.cast(belongsTo, promiseLabel);
9198
- return PromiseObject.create({
9199
- promise: promise
9200
- });
9201
- } else if (link) {
9202
- promise = store.findBelongsTo(this, link, relationshipFromMeta(store, meta));
9203
- return PromiseObject.create({
9204
- promise: promise
9205
- });
9206
- } else {
9207
- return null;
9208
- }
9209
- }).meta(meta);
9210
- }
9211
8627
 
9212
8628
  /**
9213
8629
  `DS.belongsTo` is used to define One-To-One and One-To-Many
@@ -9274,33 +8690,15 @@ define("ember-data/system/relationships/belongs_to",
9274
8690
  key: null
9275
8691
  };
9276
8692
 
9277
- if (options.async) {
9278
- return asyncBelongsTo(type, options, meta);
9279
- }
9280
-
9281
- return Ember.computed('data', function(key, value) {
9282
- var data = get(this, 'data');
9283
- var store = get(this, 'store');
9284
- var belongsTo, typeClass;
9285
-
9286
- if (typeof type === 'string') {
9287
- typeClass = store.modelFor(type);
9288
- } else {
9289
- typeClass = type;
9290
- }
9291
-
9292
- if (arguments.length === 2) {
9293
- Ember.assert("You can only add a '" + type + "' record to this relationship", !value || value instanceof typeClass);
9294
- return value === undefined ? null : value;
8693
+ return Ember.computed(function(key, value) {
8694
+ if (arguments.length>1) {
8695
+ if ( value === undefined ) {
8696
+ value = null;
8697
+ }
8698
+ this._relationships[key].setRecord(value);
9295
8699
  }
9296
8700
 
9297
- belongsTo = data[key];
9298
-
9299
- if (isNone(belongsTo)) { return null; }
9300
-
9301
- store.findById(belongsTo.constructor, belongsTo.get('id'));
9302
-
9303
- return belongsTo;
8701
+ return this._relationships[key].getRecord();
9304
8702
  }).meta(meta);
9305
8703
  }
9306
8704
 
@@ -9312,72 +8710,26 @@ define("ember-data/system/relationships/belongs_to",
9312
8710
  @namespace DS
9313
8711
  */
9314
8712
  Model.reopen({
8713
+ notifyBelongsToAdded: function(key, relationship) {
8714
+ this.notifyPropertyChange(key);
8715
+ },
9315
8716
 
9316
- /**
9317
- @method belongsToWillChange
9318
- @private
9319
- @static
9320
- @param record
9321
- @param key
9322
- */
9323
- belongsToWillChange: Ember.beforeObserver(function(record, key) {
9324
- if (get(record, 'isLoaded') && isSyncRelationship(record, key)) {
9325
- var oldParent = get(record, key);
9326
-
9327
- if (oldParent) {
9328
- var store = get(record, 'store');
9329
- var change = RelationshipChange.createChange(record, oldParent, store, {
9330
- key: key,
9331
- kind: 'belongsTo',
9332
- changeType: 'remove'
9333
- });
9334
-
9335
- change.sync();
9336
- this._changesToSync[key] = change;
9337
- }
9338
- }
9339
- }),
9340
-
9341
- /**
9342
- @method belongsToDidChange
9343
- @private
9344
- @static
9345
- @param record
9346
- @param key
9347
- */
9348
- belongsToDidChange: Ember.immediateObserver(function(record, key) {
9349
- if (get(record, 'isLoaded')) {
9350
- var newParent = get(record, key);
9351
-
9352
- if (newParent) {
9353
- var store = get(record, 'store');
9354
- var change = RelationshipChange.createChange(record, newParent, store, {
9355
- key: key,
9356
- kind: 'belongsTo',
9357
- changeType: 'add'
9358
- });
9359
-
9360
- change.sync();
9361
- }
9362
- }
9363
-
9364
- delete this._changesToSync[key];
9365
- })
8717
+ notifyBelongsToRemoved: function(key) {
8718
+ this.notifyPropertyChange(key);
8719
+ }
9366
8720
  });
9367
8721
 
9368
8722
  __exports__["default"] = belongsTo;
9369
8723
  });
9370
8724
  define("ember-data/system/relationships/ext",
9371
- ["ember-inflector/system","ember-data/system/relationship-meta","ember-data/system/model"],
9372
- function(__dependency1__, __dependency2__, __dependency3__) {
8725
+ ["ember-data/system/relationship-meta","ember-data/system/model"],
8726
+ function(__dependency1__, __dependency2__) {
9373
8727
  "use strict";
9374
- var singularize = __dependency1__.singularize;
9375
- var typeForRelationshipMeta = __dependency2__.typeForRelationshipMeta;
9376
- var relationshipFromMeta = __dependency2__.relationshipFromMeta;
9377
- var Model = __dependency3__.Model;
8728
+ var typeForRelationshipMeta = __dependency1__.typeForRelationshipMeta;
8729
+ var relationshipFromMeta = __dependency1__.relationshipFromMeta;
8730
+ var Model = __dependency2__.Model;
9378
8731
 
9379
8732
  var get = Ember.get;
9380
- var set = Ember.set;
9381
8733
 
9382
8734
  /**
9383
8735
  @module ember-data
@@ -9429,11 +8781,6 @@ define("ember-data/system/relationships/ext",
9429
8781
  // the computed property.
9430
8782
  var meta = value.meta();
9431
8783
 
9432
- if (meta.isRelationship && meta.kind === 'belongsTo') {
9433
- Ember.addObserver(proto, key, null, 'belongsToDidChange');
9434
- Ember.addBeforeObserver(proto, key, null, 'belongsToWillChange');
9435
- }
9436
-
9437
8784
  meta.parentType = proto.constructor;
9438
8785
  }
9439
8786
  }
@@ -9815,140 +9162,63 @@ define("ember-data/system/relationships/ext",
9815
9162
  get(this, 'relatedTypes').forEach(function(type) {
9816
9163
  callback.call(binding, type);
9817
9164
  });
9818
- }
9819
- });
9165
+ },
9820
9166
 
9821
- Model.reopen({
9822
- /**
9823
- Given a callback, iterates over each of the relationships in the model,
9824
- invoking the callback with the name of each relationship and its relationship
9825
- descriptor.
9167
+ determineRelationshipType: function(knownSide) {
9168
+ var knownKey = knownSide.key;
9169
+ var knownKind = knownSide.kind;
9170
+ var inverse = this.inverseFor(knownKey);
9171
+ var key, otherKind;
9826
9172
 
9827
- @method eachRelationship
9828
- @param {Function} callback the callback to invoke
9829
- @param {any} binding the value to which the callback's `this` should be bound
9830
- */
9831
- eachRelationship: function(callback, binding) {
9832
- this.constructor.eachRelationship(callback, binding);
9833
- }
9834
- });
9835
- });
9836
- define("ember-data/system/relationships/has_many",
9837
- ["ember-data/system/store","ember-data/system/relationship-meta","exports"],
9838
- function(__dependency1__, __dependency2__, __exports__) {
9839
- "use strict";
9840
- /**
9841
- @module ember-data
9842
- */
9843
-
9844
- var PromiseArray = __dependency1__.PromiseArray;
9173
+ if (!inverse) {
9174
+ return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
9175
+ }
9845
9176
 
9846
- var relationshipFromMeta = __dependency2__.relationshipFromMeta;
9847
- var typeForRelationshipMeta = __dependency2__.typeForRelationshipMeta;
9177
+ key = inverse.name;
9178
+ otherKind = inverse.kind;
9848
9179
 
9849
- var get = Ember.get;
9850
- var set = Ember.set;
9851
- var setProperties = Ember.setProperties;
9852
- var map = Ember.EnumerableUtils.map;
9180
+ if (otherKind === 'belongsTo') {
9181
+ return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
9182
+ } else {
9183
+ return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
9184
+ }
9185
+ }
9853
9186
 
9854
- /**
9855
- Returns a computed property that synchronously returns a ManyArray for
9856
- this relationship. If not all of the records in this relationship are
9857
- loaded, it will raise an exception.
9858
- */
9187
+ });
9859
9188
 
9860
- function syncHasMany(type, options, meta) {
9861
- return Ember.computed('data', function(key) {
9862
- return buildRelationship(this, key, options, function(store, data) {
9863
- // Configure the metadata for the computed property to contain
9864
- // the key.
9865
- meta.key = key;
9189
+ Model.reopen({
9190
+ /**
9191
+ Given a callback, iterates over each of the relationships in the model,
9192
+ invoking the callback with the name of each relationship and its relationship
9193
+ descriptor.
9866
9194
 
9867
- var records = data[key];
9195
+ @method eachRelationship
9196
+ @param {Function} callback the callback to invoke
9197
+ @param {any} binding the value to which the callback's `this` should be bound
9198
+ */
9199
+ eachRelationship: function(callback, binding) {
9200
+ this.constructor.eachRelationship(callback, binding);
9201
+ },
9868
9202
 
9869
- Ember.assert("You looked up the '" + key + "' relationship on '" + this + "' but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)", Ember.A(records).isEvery('isEmpty', false));
9203
+ relationshipFor: function(name) {
9204
+ return get(this.constructor, 'relationshipsByName').get(name);
9205
+ },
9870
9206
 
9871
- return store.findMany(this, data[key], typeForRelationshipMeta(store, meta));
9872
- });
9873
- }).meta(meta).readOnly();
9874
- }
9207
+ inverseFor: function(key) {
9208
+ return this.constructor.inverseFor(key);
9209
+ }
9875
9210
 
9211
+ });
9212
+ });
9213
+ define("ember-data/system/relationships/has_many",
9214
+ ["ember-data/system/model","exports"],
9215
+ function(__dependency1__, __exports__) {
9216
+ "use strict";
9876
9217
  /**
9877
- Returns a computed property that itself returns a promise that resolves to a
9878
- ManyArray.
9879
- */
9880
-
9881
- function asyncHasMany(type, options, meta) {
9882
- return Ember.computed('data', function(key) {
9883
- // Configure the metadata for the computed property to contain
9884
- // the key.
9885
- meta.key = key;
9886
-
9887
- var relationship = buildRelationship(this, key, options, function(store, data) {
9888
- var link = data.links && data.links[key];
9889
- var rel;
9890
- var promiseLabel = "DS: Async hasMany " + this + " : " + key;
9891
- var resolver = Ember.RSVP.defer(promiseLabel);
9892
-
9893
- if (link) {
9894
- rel = store.findHasMany(this, link, relationshipFromMeta(store, meta), resolver);
9895
- } else {
9896
-
9897
- //This is a temporary workaround for setting owner on the relationship
9898
- //until single source of truth lands. It only works for OneToMany atm
9899
- var records = data[key];
9900
- var inverse = this.constructor.inverseFor(key);
9901
- var owner = this;
9902
- if (inverse && records) {
9903
- if (inverse.kind === 'belongsTo'){
9904
- map(records, function(record){
9905
- set(record, inverse.name, owner);
9906
- });
9907
- }
9908
- }
9909
-
9910
- rel = store.findMany(owner, data[key], typeForRelationshipMeta(store, meta), resolver);
9911
- }
9912
-
9913
- // Cache the promise so we can use it when we come back and don't
9914
- // need to rebuild the relationship.
9915
- set(rel, 'promise', resolver.promise);
9916
-
9917
- return rel;
9918
- });
9919
-
9920
- var promise = relationship.get('promise').then(function() {
9921
- return relationship;
9922
- }, null, "DS: Async hasMany records received");
9923
-
9924
- return PromiseArray.create({
9925
- promise: promise
9926
- });
9927
- }).meta(meta).readOnly();
9928
- }
9929
-
9930
- /*
9931
- Builds the ManyArray for a relationship using the provided callback,
9932
- but only if it had not been created previously. After building, it
9933
- sets some metadata on the created ManyArray, such as the record which
9934
- owns it and the name of the relationship.
9218
+ @module ember-data
9935
9219
  */
9936
- function buildRelationship(record, key, options, callback) {
9937
- var rels = record._relationships;
9938
9220
 
9939
- if (rels[key]) { return rels[key]; }
9940
-
9941
- var data = get(record, 'data');
9942
- var store = get(record, 'store');
9943
-
9944
- var relationship = rels[key] = callback.call(record, store, data);
9945
-
9946
- return setProperties(relationship, {
9947
- owner: record,
9948
- name: key,
9949
- isPolymorphic: options.polymorphic
9950
- });
9951
- }
9221
+ var Model = __dependency1__.Model;
9952
9222
 
9953
9223
  /**
9954
9224
  `DS.hasMany` is used to define One-To-Many and Many-To-Many
@@ -10048,18 +9318,317 @@ define("ember-data/system/relationships/has_many",
10048
9318
  key: null
10049
9319
  };
10050
9320
 
10051
- if (options.async) {
10052
- return asyncHasMany(type, options, meta);
9321
+ return Ember.computed(function(key) {
9322
+ var relationship = this._relationships[key];
9323
+ return relationship.getRecords();
9324
+ }).meta(meta).readOnly();
9325
+ }
9326
+
9327
+ Model.reopen({
9328
+ notifyHasManyAdded: function(key, record, idx) {
9329
+ var relationship = this._relationships[key];
9330
+ var manyArray = relationship.manyArray;
9331
+ manyArray.addRecord(record, idx);
9332
+ //We need to notifyPropertyChange in the adding case because we need to make sure
9333
+ //we fetch the newly added record in case it is unloaded
9334
+ //TODO(Igor): Consider whether we could do this only if the record state is unloaded
9335
+ this.notifyPropertyChange(key);
9336
+ },
9337
+
9338
+ notifyHasManyRemoved: function(key, record) {
9339
+ var relationship = this._relationships[key];
9340
+ var manyArray = relationship.manyArray;
9341
+ manyArray.removeRecord(record);
9342
+ }
9343
+ });
9344
+
9345
+
9346
+ __exports__["default"] = hasMany;
9347
+ });
9348
+ define("ember-data/system/relationships/relationship",
9349
+ ["ember-data/system/promise_proxies","exports"],
9350
+ function(__dependency1__, __exports__) {
9351
+ "use strict";
9352
+ var PromiseArray = __dependency1__.PromiseArray;
9353
+ var PromiseObject = __dependency1__.PromiseObject;
9354
+
9355
+ var Relationship = function(store, record, inverseKey, relationshipMeta) {
9356
+ this.members = new Ember.OrderedSet();
9357
+ this.store = store;
9358
+ this.key = relationshipMeta.key;
9359
+ this.inverseKey = inverseKey;
9360
+ this.record = record;
9361
+ this.key = relationshipMeta.key;
9362
+ this.isAsync = relationshipMeta.options.async;
9363
+ this.relationshipMeta = relationshipMeta;
9364
+ };
9365
+
9366
+ Relationship.prototype = {
9367
+ constructor: Relationship,
9368
+ hasFetchedLink: false,
9369
+
9370
+ destroy: Ember.K,
9371
+
9372
+ clear: function() {
9373
+ this.members.forEach(function(member) {
9374
+ this.removeRecord(member);
9375
+ }, this);
9376
+ },
9377
+
9378
+ removeRecords: function(records){
9379
+ var that = this;
9380
+ records.forEach(function(record){
9381
+ that.removeRecord(record);
9382
+ });
9383
+ },
9384
+
9385
+ addRecords: function(records, idx){
9386
+ var that = this;
9387
+ records.forEach(function(record){
9388
+ that.addRecord(record, idx);
9389
+ if (idx !== undefined) {
9390
+ idx++;
9391
+ }
9392
+ });
9393
+ },
9394
+
9395
+
9396
+ addRecord: function(record, idx) {
9397
+ if (!this.members.has(record)) {
9398
+ this.members.add(record);
9399
+ this.notifyRecordRelationshipAdded(record, idx);
9400
+ if (this.inverseKey) {
9401
+ record._relationships[this.inverseKey].addRecord(this.record);
9402
+ }
9403
+ this.record.updateRecordArrays();
9404
+ }
9405
+ },
9406
+
9407
+ removeRecord: function(record) {
9408
+ if (this.members.has(record)) {
9409
+ this.members.remove(record);
9410
+ this.notifyRecordRelationshipRemoved(record);
9411
+ if (this.inverseKey) {
9412
+ var inverseRelationship = record._relationships[this.inverseKey];
9413
+ //Need to check for existence, as the record might unloading at the moment
9414
+ if (inverseRelationship) {
9415
+ inverseRelationship.removeRecord(this.record);
9416
+ }
9417
+ }
9418
+ this.record.updateRecordArrays();
9419
+ }
9420
+ },
9421
+
9422
+ updateLink: function(link) {
9423
+ if (link !== this.link) {
9424
+ this.link = link;
9425
+ this.hasFetchedLink = false;
9426
+ this.record.notifyPropertyChange(this.key);
9427
+ }
9428
+ },
9429
+
9430
+ updateRecordsFromAdapter: function(records) {
9431
+ //TODO Once we have adapter support, we need to handle updated and canonical changes
9432
+ this.computeChanges(records);
9433
+ }
9434
+ };
9435
+
9436
+ var ManyRelationship = function(store, record, inverseKey, relationshipMeta) {
9437
+ this._super$constructor(store, record, inverseKey, relationshipMeta);
9438
+ this.belongsToType = relationshipMeta.type;
9439
+ this.manyArray = store.recordArrayManager.createManyArray(this.belongsToType, Ember.A());
9440
+ this.manyArray.relationship = this;
9441
+ this.isPolymorphic = relationshipMeta.options.polymorphic;
9442
+ this.manyArray.isPolymorphic = this.isPolymorphic;
9443
+ };
9444
+
9445
+ ManyRelationship.prototype = Object.create(Relationship.prototype);
9446
+ ManyRelationship.prototype.constructor = ManyRelationship;
9447
+ ManyRelationship.prototype._super$constructor = Relationship;
9448
+
9449
+ ManyRelationship.prototype.destroy = function() {
9450
+ this.manyArray.destroy();
9451
+ };
9452
+
9453
+ ManyRelationship.prototype.notifyRecordRelationshipAdded = function(record, idx) {
9454
+ Ember.assert("You cannot add '" + record.constructor.typeKey + "' records to this relationship (only '" + this.belongsToType.typeKey + "' allowed)", !this.belongsToType || record instanceof this.belongsToType);
9455
+ this.record.notifyHasManyAdded(this.key, record, idx);
9456
+ };
9457
+
9458
+ ManyRelationship.prototype.notifyRecordRelationshipRemoved = function(record) {
9459
+ this.record.notifyHasManyRemoved(this.key, record);
9460
+ };
9461
+
9462
+ ManyRelationship.prototype.computeChanges = function(records) {
9463
+ var members = this.members;
9464
+
9465
+ records = setForArray(records);
9466
+
9467
+ members.forEach(function(member) {
9468
+ if (records.has(member)) return;
9469
+
9470
+ this.removeRecord(member);
9471
+ }, this);
9472
+
9473
+ var hasManyArray = this.manyArray;
9474
+
9475
+ records.forEach(function(record, index) {
9476
+ //Need to preserve the order of incoming records
9477
+ if (hasManyArray.objectAt(index) === record ) return;
9478
+
9479
+ this.removeRecord(record);
9480
+ this.addRecord(record, index);
9481
+ }, this);
9482
+ };
9483
+
9484
+
9485
+ ManyRelationship.prototype.getRecords = function() {
9486
+ if (this.isAsync) {
9487
+ var self = this;
9488
+ var promise;
9489
+ if (this.link && !this.hasFetchedLink) {
9490
+ promise = this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records){
9491
+ self.updateRecordsFromAdapter(records);
9492
+ self.hasFetchedLink = true;
9493
+ //TODO(Igor) try to abstract the isLoaded part
9494
+ self.manyArray.set('isLoaded', true);
9495
+ return self.manyArray;
9496
+ });
9497
+ } else {
9498
+ var manyArray = this.manyArray;
9499
+ promise = this.store.findMany(manyArray.toArray()).then(function(){
9500
+ self.manyArray.set('isLoaded', true);
9501
+ return manyArray;
9502
+ });
9503
+ }
9504
+ return PromiseArray.create({
9505
+ promise: promise
9506
+ });
10053
9507
  } else {
10054
- return syncHasMany(type, options, meta);
9508
+ Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)", this.manyArray.isEvery('isEmpty', false));
9509
+
9510
+ this.manyArray.set('isLoaded', true);
9511
+ return this.manyArray;
9512
+ }
9513
+ };
9514
+
9515
+ var BelongsToRelationship = function(store, record, inverseKey, relationshipMeta) {
9516
+ this._super$constructor(store, record, inverseKey, relationshipMeta);
9517
+ this.members.add(record);
9518
+ this.record = record;
9519
+ this.key = relationshipMeta.key;
9520
+ this.inverseKey = inverseKey;
9521
+ this.inverseRecord = null;
9522
+ };
9523
+
9524
+ BelongsToRelationship.prototype = Object.create(Relationship.prototype);
9525
+ BelongsToRelationship.prototype.constructor = BelongsToRelationship;
9526
+ BelongsToRelationship.prototype._super$constructor = Relationship;
9527
+
9528
+ BelongsToRelationship.prototype.setRecord = function(newRecord) {
9529
+ if (newRecord) {
9530
+ this.addRecord(newRecord);
9531
+ } else if (this.inverseRecord) {
9532
+ this.removeRecord(this.inverseRecord);
10055
9533
  }
9534
+ };
9535
+
9536
+ BelongsToRelationship.prototype._super$addRecord = Relationship.prototype.addRecord;
9537
+ BelongsToRelationship.prototype.addRecord = function(newRecord) {
9538
+ if (this.members.has(newRecord)){ return;}
9539
+ var type = this.relationshipMeta.type;
9540
+ Ember.assert("You can only add a '" + type.typeKey + "' record to this relationship", newRecord instanceof type);
9541
+
9542
+ if (this.inverseRecord && this.inverseKey) {
9543
+ this.removeRecord(this.inverseRecord);
9544
+ }
9545
+
9546
+ this.inverseRecord = newRecord;
9547
+ this._super$addRecord(newRecord);
9548
+ };
9549
+
9550
+ BelongsToRelationship.prototype.notifyRecordRelationshipAdded = function(newRecord) {
9551
+ this.record.notifyBelongsToAdded(this.key, this);
9552
+ };
9553
+
9554
+ BelongsToRelationship.prototype.notifyRecordRelationshipRemoved = function(record) {
9555
+ this.record.notifyBelongsToRemoved(this.key, this);
9556
+ };
9557
+
9558
+ BelongsToRelationship.prototype._super$removeRecord = Relationship.prototype.removeRecord;
9559
+ BelongsToRelationship.prototype.removeRecord = function(record) {
9560
+ if (!this.members.has(record)){ return;}
9561
+ this._super$removeRecord(record);
9562
+ this.inverseRecord = null;
9563
+ };
9564
+
9565
+ BelongsToRelationship.prototype.currentOtherSideFor = function() {
9566
+ return this.inverseRecord;
9567
+ };
9568
+
9569
+ BelongsToRelationship.prototype.getRecord = function() {
9570
+ if (this.isAsync) {
9571
+ var promise;
9572
+
9573
+ if (this.link && !this.hasFetchedLink){
9574
+ var self = this;
9575
+ promise = this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record){
9576
+ self.addRecord(record);
9577
+ self.hasFetchedLink = true;
9578
+ return record;
9579
+ });
9580
+ } else if (this.inverseRecord) {
9581
+ promise = this.store._findByRecord(this.inverseRecord);
9582
+ } else {
9583
+ promise = Ember.RSVP.Promise.resolve(null);
9584
+ }
9585
+
9586
+ return PromiseObject.create({
9587
+ promise: promise
9588
+ });
9589
+ } else {
9590
+ Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.belongsTo({ async: true })`)", this.inverseRecord === null || !this.inverseRecord.get('isEmpty'));
9591
+ return this.inverseRecord;
9592
+ }
9593
+ };
9594
+
9595
+ function setForArray(array) {
9596
+ var set = new Ember.OrderedSet();
9597
+
9598
+ if (array) {
9599
+ for (var i=0, l=array.length; i<l; i++) {
9600
+ set.add(array[i]);
9601
+ }
9602
+ }
9603
+
9604
+ return set;
10056
9605
  }
10057
9606
 
10058
- __exports__["default"] = hasMany;
9607
+ var createRelationshipFor = function(record, relationshipMeta, store){
9608
+ var inverseKey;
9609
+ var inverse = record.constructor.inverseFor(relationshipMeta.key);
9610
+
9611
+ if (inverse) {
9612
+ inverseKey = inverse.name;
9613
+ }
9614
+
9615
+ if (relationshipMeta.kind === 'hasMany'){
9616
+ return new ManyRelationship(store, record, inverseKey, relationshipMeta);
9617
+ }
9618
+ else {
9619
+ return new BelongsToRelationship(store, record, inverseKey, relationshipMeta);
9620
+ }
9621
+ };
9622
+
9623
+
9624
+ __exports__.Relationship = Relationship;
9625
+ __exports__.ManyRelationship = ManyRelationship;
9626
+ __exports__.BelongsToRelationship = BelongsToRelationship;
9627
+ __exports__.createRelationshipFor = createRelationshipFor;
10059
9628
  });
10060
9629
  define("ember-data/system/store",
10061
- ["ember-data/system/adapter","ember-inflector/system/string","exports"],
10062
- function(__dependency1__, __dependency2__, __exports__) {
9630
+ ["ember-data/system/adapter","ember-inflector/system/string","ember-data/system/promise_proxies","exports"],
9631
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
10063
9632
  "use strict";
10064
9633
  /*globals Ember*/
10065
9634
  /*jshint eqnull:true*/
@@ -10072,6 +9641,10 @@ define("ember-data/system/store",
10072
9641
  var Adapter = __dependency1__.Adapter;
10073
9642
  var singularize = __dependency2__.singularize;
10074
9643
 
9644
+ var promiseArray = __dependency3__.promiseArray;
9645
+ var promiseObject = __dependency3__.promiseObject;
9646
+
9647
+
10075
9648
  var get = Ember.get;
10076
9649
  var set = Ember.set;
10077
9650
  var once = Ember.run.once;
@@ -10081,7 +9654,7 @@ define("ember-data/system/store",
10081
9654
  var map = Ember.EnumerableUtils.map;
10082
9655
  var Promise = Ember.RSVP.Promise;
10083
9656
  var copy = Ember.copy;
10084
- var Store, PromiseObject, PromiseArray, RecordArrayManager, Model;
9657
+ var Store, RecordArrayManager, Model;
10085
9658
 
10086
9659
  var camelize = Ember.String.camelize;
10087
9660
 
@@ -10202,7 +9775,6 @@ define("ember-data/system/store",
10202
9775
  this.recordArrayManager = RecordArrayManager.create({
10203
9776
  store: this
10204
9777
  });
10205
- this._relationshipChanges = {};
10206
9778
  this._pendingSave = [];
10207
9779
  //Used to keep track of all the find requests that need to be coalesced
10208
9780
  this._pendingFetch = Ember.Map.create();
@@ -10414,10 +9986,10 @@ define("ember-data/system/store",
10414
9986
 
10415
9987
  ---
10416
9988
 
10417
- You can optionally preload specific attributes and relationships that you know of
9989
+ You can optionally `preload` specific attributes and relationships that you know of
10418
9990
  by passing them as the third argument to find.
10419
9991
 
10420
- For example, if your Ember route looks like `/posts/1/comments/2` and you API route
9992
+ For example, if your Ember route looks like `/posts/1/comments/2` and your API route
10421
9993
  for the comment also looks like `/posts/1/comments/2` if you want to fetch the comment
10422
9994
  without fetching the post you can pass in the post to the `find` call:
10423
9995
 
@@ -10465,6 +10037,7 @@ define("ember-data/system/store",
10465
10037
  @method find
10466
10038
  @param {String or subclass of DS.Model} type
10467
10039
  @param {Object|String|Integer|null} id
10040
+ @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
10468
10041
  @return {Promise} promise
10469
10042
  */
10470
10043
  find: function(type, id, preload) {
@@ -10490,14 +10063,20 @@ define("ember-data/system/store",
10490
10063
  @private
10491
10064
  @param {String or subclass of DS.Model} type
10492
10065
  @param {String|Integer} id
10066
+ @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
10493
10067
  @return {Promise} promise
10494
10068
  */
10495
10069
  findById: function(typeName, id, preload) {
10496
- var fetchedRecord;
10497
10070
 
10498
10071
  var type = this.modelFor(typeName);
10499
10072
  var record = this.recordForId(type, id);
10500
10073
 
10074
+ return this._findByRecord(record, preload);
10075
+ },
10076
+
10077
+ _findByRecord: function(record, preload) {
10078
+ var fetchedRecord;
10079
+
10501
10080
  if (preload) {
10502
10081
  record._preloadData(preload);
10503
10082
  }
@@ -10509,7 +10088,7 @@ define("ember-data/system/store",
10509
10088
  fetchedRecord = record._loadingPromise;
10510
10089
  }
10511
10090
 
10512
- return promiseObject(fetchedRecord || record, "DS: Store#findById " + type + " with id: " + id);
10091
+ return promiseObject(fetchedRecord || record, "DS: Store#findByRecord " + record.typeKey + " with id: " + get(record, 'id'));
10513
10092
  },
10514
10093
 
10515
10094
  /**
@@ -10524,7 +10103,6 @@ define("ember-data/system/store",
10524
10103
  */
10525
10104
  findByIds: function(type, ids) {
10526
10105
  var store = this;
10527
- var promiseLabel = "DS: Store#findByIds " + type;
10528
10106
 
10529
10107
  return promiseArray(Ember.RSVP.all(map(ids, function(id) {
10530
10108
  return store.findById(type, id);
@@ -10595,7 +10173,6 @@ define("ember-data/system/store",
10595
10173
  var adapter = store.adapterFor(type);
10596
10174
  var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
10597
10175
  var records = Ember.A(recordResolverPairs).mapBy('record');
10598
- var resolvers = Ember.A(recordResolverPairs).mapBy('resolver');
10599
10176
 
10600
10177
  function _fetchRecord(recordResolverPair) {
10601
10178
  recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record));
@@ -10756,29 +10333,14 @@ define("ember-data/system/store",
10756
10333
  @param {Resolver} resolver
10757
10334
  @return {DS.ManyArray} records
10758
10335
  */
10759
- findMany: function(owner, inputRecords, typeName, resolver) {
10760
- var type = this.modelFor(typeName);
10761
- var records = Ember.A(inputRecords);
10762
- var unloadedRecords = records.filterProperty('isEmpty', true);
10763
- var manyArray = this.recordArrayManager.createManyArray(type, records);
10764
-
10765
- manyArray.loadingRecordsCount = unloadedRecords.length;
10766
-
10767
- if (unloadedRecords.length) {
10768
- forEach(unloadedRecords, function(record) {
10769
- this.recordArrayManager.registerWaitingRecordArray(record, manyArray);
10770
- }, this);
10771
-
10772
- resolver.resolve(this.scheduleFetchMany(unloadedRecords, owner));
10773
- } else {
10774
- if (resolver) { resolver.resolve(); }
10775
- manyArray.set('isLoaded', true);
10776
- once(manyArray, 'trigger', 'didLoad');
10777
- }
10778
-
10779
- return manyArray;
10336
+ findMany: function(records) {
10337
+ var store = this;
10338
+ return Promise.all( map(records, function(record) {
10339
+ return store._findByRecord(record);
10340
+ }));
10780
10341
  },
10781
10342
 
10343
+
10782
10344
  /**
10783
10345
  If a relationship was originally populated by the adapter as a link
10784
10346
  (as opposed to a list of IDs), this method is called when the
@@ -10797,15 +10359,13 @@ define("ember-data/system/store",
10797
10359
  @param {String or subclass of DS.Model} type
10798
10360
  @return {Promise} promise
10799
10361
  */
10800
- findHasMany: function(owner, link, relationship, resolver) {
10362
+ findHasMany: function(owner, link, type) {
10801
10363
  var adapter = this.adapterFor(owner.constructor);
10802
10364
 
10803
10365
  Ember.assert("You tried to load a hasMany relationship but you have no adapter (for " + owner.constructor + ")", adapter);
10804
10366
  Ember.assert("You tried to load a hasMany relationship from a specified `link` in the original payload but your adapter does not implement `findHasMany`", adapter.findHasMany);
10805
10367
 
10806
- var records = this.recordArrayManager.createManyArray(relationship.type, Ember.A([]));
10807
- resolver.resolve(_findHasMany(adapter, this, owner, link, relationship));
10808
- return records;
10368
+ return _findHasMany(adapter, this, owner, link, type);
10809
10369
  },
10810
10370
 
10811
10371
  /**
@@ -11151,6 +10711,7 @@ define("ember-data/system/store",
11151
10711
  if (data) {
11152
10712
  // normalize relationship IDs into records
11153
10713
  data = normalizeRelationships(this, record.constructor, data, record);
10714
+ setupRelationships(this, record, data);
11154
10715
 
11155
10716
  this.updateId(record, data);
11156
10717
  }
@@ -11272,11 +10833,11 @@ define("ember-data/system/store",
11272
10833
  var factory;
11273
10834
 
11274
10835
  if (typeof key === 'string') {
11275
- var normalizedKey = this.container.normalize('model:' + key);
11276
-
11277
- factory = this.container.lookupFactory(normalizedKey);
11278
- if (!factory) { throw new Ember.Error("No model was found for '" + key + "'"); }
11279
- factory.typeKey = this._normalizeTypeKey(normalizedKey.split(':', 2)[1]);
10836
+ factory = this.container.lookupFactory('model:' + key);
10837
+ if (!factory) {
10838
+ throw new Ember.Error("No model was found for '" + key + "'");
10839
+ }
10840
+ factory.typeKey = factory.typeKey || this._normalizeTypeKey(key);
11280
10841
  } else {
11281
10842
  // A factory already supplied. Ensure it has a normalized key.
11282
10843
  factory = key;
@@ -11354,17 +10915,30 @@ define("ember-data/system/store",
11354
10915
  // _partial is an internal param used by `update`.
11355
10916
  // If passed, it means that the data should be
11356
10917
  // merged into the existing data, not replace it.
11357
-
11358
- Ember.assert("You must include an `id` for " + typeName+ " in a hash passed to `push`", data.id != null);
10918
+ Ember.assert("Expected an object as `data` in a call to push for " + typeName + " , but was " + data, Ember.typeOf(data) === 'object');
10919
+ Ember.assert("You must include an `id` for " + typeName + " in an object passed to `push`", data.id != null);
11359
10920
 
11360
10921
  var type = this.modelFor(typeName);
11361
10922
 
11362
- // normalize relationship IDs into records
10923
+ // If the payload contains relationships that are specified as
10924
+ // IDs, normalizeRelationships will convert them into DS.Model instances
10925
+ // (possibly unloaded) before we push the payload into the
10926
+ // store.
10927
+
11363
10928
  data = normalizeRelationships(this, type, data);
11364
10929
 
10930
+ // Actually load the record into the store.
10931
+
11365
10932
  this._load(type, data, _partial);
11366
10933
 
11367
- return this.recordForId(type, data.id);
10934
+ var record = this.recordForId(type, data.id);
10935
+
10936
+ // Now that the pushed record as well as any related records
10937
+ // are in the store, create the data structures used to track
10938
+ // relationships.
10939
+ setupRelationships(this, record, data);
10940
+
10941
+ return record;
11368
10942
  },
11369
10943
 
11370
10944
  /**
@@ -11499,9 +11073,14 @@ define("ember-data/system/store",
11499
11073
  @return {Array}
11500
11074
  */
11501
11075
  pushMany: function(type, datas) {
11502
- return map(datas, function(data) {
11503
- return this.push(type, data);
11504
- }, this);
11076
+ var length = datas.length;
11077
+ var result = new Array(length);
11078
+
11079
+ for (var i = 0; i < length; i++) {
11080
+ result[i] = this.push(type, datas[i]);
11081
+ }
11082
+
11083
+ return result;
11505
11084
  },
11506
11085
 
11507
11086
  /**
@@ -11586,59 +11165,6 @@ define("ember-data/system/store",
11586
11165
  typeMap.records.splice(loc, 1);
11587
11166
  },
11588
11167
 
11589
- // ........................
11590
- // . RELATIONSHIP CHANGES .
11591
- // ........................
11592
-
11593
- addRelationshipChangeFor: function(childRecord, childKey, parentRecord, parentKey, change) {
11594
- var clientId = childRecord.clientId;
11595
- var parentClientId = parentRecord ? parentRecord : parentRecord;
11596
- var key = childKey + parentKey;
11597
- var changes = this._relationshipChanges;
11598
-
11599
- if (!(clientId in changes)) {
11600
- changes[clientId] = {};
11601
- }
11602
- if (!(parentClientId in changes[clientId])) {
11603
- changes[clientId][parentClientId] = {};
11604
- }
11605
- if (!(key in changes[clientId][parentClientId])) {
11606
- changes[clientId][parentClientId][key] = {};
11607
- }
11608
- changes[clientId][parentClientId][key][change.changeType] = change;
11609
- },
11610
-
11611
- removeRelationshipChangeFor: function(clientRecord, childKey, parentRecord, parentKey, type) {
11612
- var clientId = clientRecord.clientId;
11613
- var parentClientId = parentRecord ? parentRecord.clientId : parentRecord;
11614
- var changes = this._relationshipChanges;
11615
- var key = childKey + parentKey;
11616
-
11617
- if (!(clientId in changes) || !(parentClientId in changes[clientId]) || !(key in changes[clientId][parentClientId])){
11618
- return;
11619
- }
11620
- delete changes[clientId][parentClientId][key][type];
11621
- },
11622
-
11623
- relationshipChangePairsFor: function(record){
11624
- var toReturn = [];
11625
-
11626
- if( !record ) { return toReturn; }
11627
-
11628
- //TODO(Igor) What about the other side
11629
- var changesObject = this._relationshipChanges[record.clientId];
11630
- for (var objKey in changesObject){
11631
- if (changesObject.hasOwnProperty(objKey)){
11632
- for (var changeKey in changesObject[objKey]){
11633
- if (changesObject[objKey].hasOwnProperty(changeKey)){
11634
- toReturn.push(changesObject[objKey][changeKey]);
11635
- }
11636
- }
11637
- }
11638
- }
11639
- return toReturn;
11640
- },
11641
-
11642
11168
  // ......................
11643
11169
  // . PER-TYPE ADAPTERS
11644
11170
  // ......................
@@ -11692,7 +11218,6 @@ define("ember-data/system/store",
11692
11218
  willDestroy: function() {
11693
11219
  var typeMaps = this.typeMaps;
11694
11220
  var keys = Ember.keys(typeMaps);
11695
- var store = this;
11696
11221
 
11697
11222
  var types = map(keys, byType);
11698
11223
 
@@ -11720,30 +11245,15 @@ define("ember-data/system/store",
11720
11245
  }
11721
11246
  });
11722
11247
 
11248
+
11723
11249
  function normalizeRelationships(store, type, data, record) {
11724
11250
  type.eachRelationship(function(key, relationship) {
11725
- // A link (usually a URL) was already provided in
11726
- // normalized form
11727
- if (data.links && data.links[key]) {
11728
- if (record && relationship.options.async) { record._relationships[key] = null; }
11729
- return;
11730
- }
11731
-
11732
11251
  var kind = relationship.kind;
11733
11252
  var value = data[key];
11734
-
11735
- if (value == null) {
11736
- if (kind === 'hasMany' && record) {
11737
- value = data[key] = record.get(key).toArray();
11738
- }
11739
- return;
11740
- }
11741
-
11742
11253
  if (kind === 'belongsTo') {
11743
11254
  deserializeRecordId(store, data, key, relationship, value);
11744
11255
  } else if (kind === 'hasMany') {
11745
11256
  deserializeRecordIds(store, data, key, relationship, value);
11746
- addUnsavedRecords(record, key, value);
11747
11257
  }
11748
11258
  });
11749
11259
 
@@ -11776,104 +11286,16 @@ define("ember-data/system/store",
11776
11286
  }
11777
11287
 
11778
11288
  function deserializeRecordIds(store, data, key, relationship, ids) {
11289
+ if (!Ember.isArray(ids)) {
11290
+ return;
11291
+ }
11779
11292
  for (var i=0, l=ids.length; i<l; i++) {
11780
11293
  deserializeRecordId(store, ids, i, relationship, ids[i]);
11781
11294
  }
11782
11295
  }
11783
11296
 
11784
- // If there are any unsaved records that are in a hasMany they won't be
11785
- // in the payload, so add them back in manually.
11786
- function addUnsavedRecords(record, key, data) {
11787
- if(record) {
11788
- var unsavedRecords = uniqById(Ember.A(data), record.get(key).filterBy('isNew'));
11789
- Ember.A(data).pushObjects(unsavedRecords);
11790
- }
11791
- }
11792
-
11793
- function uniqById(data, records) {
11794
- var currentIds = data.mapBy("id");
11795
- return records.reject(function(record) {
11796
- return Ember.A(currentIds).contains(record.id);
11797
- });
11798
- }
11799
-
11800
11297
  // Delegation to the adapter and promise management
11801
- /**
11802
- A `PromiseArray` is an object that acts like both an `Ember.Array`
11803
- and a promise. When the promise is resolved the resulting value
11804
- will be set to the `PromiseArray`'s `content` property. This makes
11805
- it easy to create data bindings with the `PromiseArray` that will be
11806
- updated when the promise resolves.
11807
11298
 
11808
- For more information see the [Ember.PromiseProxyMixin
11809
- documentation](/api/classes/Ember.PromiseProxyMixin.html).
11810
-
11811
- Example
11812
-
11813
- ```javascript
11814
- var promiseArray = DS.PromiseArray.create({
11815
- promise: $.getJSON('/some/remote/data.json')
11816
- });
11817
-
11818
- promiseArray.get('length'); // 0
11819
-
11820
- promiseArray.then(function() {
11821
- promiseArray.get('length'); // 100
11822
- });
11823
- ```
11824
-
11825
- @class PromiseArray
11826
- @namespace DS
11827
- @extends Ember.ArrayProxy
11828
- @uses Ember.PromiseProxyMixin
11829
- */
11830
- PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
11831
- /**
11832
- A `PromiseObject` is an object that acts like both an `Ember.Object`
11833
- and a promise. When the promise is resolved, then the resulting value
11834
- will be set to the `PromiseObject`'s `content` property. This makes
11835
- it easy to create data bindings with the `PromiseObject` that will
11836
- be updated when the promise resolves.
11837
-
11838
- For more information see the [Ember.PromiseProxyMixin
11839
- documentation](/api/classes/Ember.PromiseProxyMixin.html).
11840
-
11841
- Example
11842
-
11843
- ```javascript
11844
- var promiseObject = DS.PromiseObject.create({
11845
- promise: $.getJSON('/some/remote/data.json')
11846
- });
11847
-
11848
- promiseObject.get('name'); // null
11849
-
11850
- promiseObject.then(function() {
11851
- promiseObject.get('name'); // 'Tomster'
11852
- });
11853
- ```
11854
-
11855
- @class PromiseObject
11856
- @namespace DS
11857
- @extends Ember.ObjectProxy
11858
- @uses Ember.PromiseProxyMixin
11859
- */
11860
- PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
11861
-
11862
- function promiseObject(promise, label) {
11863
- return PromiseObject.create({
11864
- promise: Promise.cast(promise, label)
11865
- });
11866
- }
11867
-
11868
- function promiseArray(promise, label) {
11869
- return PromiseArray.create({
11870
- promise: Promise.cast(promise, label)
11871
- });
11872
- }
11873
-
11874
- function isThenable(object) {
11875
- return object && typeof object.then === 'function';
11876
- }
11877
11299
 
11878
11300
  function serializerFor(container, type, defaultSerializer) {
11879
11301
  return container.lookup('serializer:'+type) ||
@@ -11959,8 +11381,6 @@ define("ember-data/system/store",
11959
11381
  throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
11960
11382
  }
11961
11383
 
11962
- var guardedPromise;
11963
-
11964
11384
  promise = Promise.cast(promise, label);
11965
11385
  promise = _guard(promise, _bind(_objectIsAlive, store));
11966
11386
 
@@ -11988,7 +11408,7 @@ define("ember-data/system/store",
11988
11408
  Ember.assert("The response from a findHasMany must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
11989
11409
 
11990
11410
  var records = store.pushMany(relationship.type, payload);
11991
- record.updateHasMany(relationship.key, records);
11411
+ return records;
11992
11412
  }, null, "DS: Extract payload of " + record + " : hasMany " + relationship.type);
11993
11413
  }
11994
11414
 
@@ -12004,8 +11424,6 @@ define("ember-data/system/store",
12004
11424
  return promise.then(function(adapterPayload) {
12005
11425
  var payload = serializer.extract(store, relationship.type, adapterPayload, null, 'findBelongsTo');
12006
11426
  var record = store.push(relationship.type, payload);
12007
-
12008
- record.updateBelongsTo(relationship.key, record);
12009
11427
  return record;
12010
11428
  }, null, "DS: Extract payload of " + record + " : " + relationship.type);
12011
11429
  }
@@ -12081,10 +11499,30 @@ define("ember-data/system/store",
12081
11499
  }, label);
12082
11500
  }
12083
11501
 
12084
- __exports__.Store = Store;
12085
- __exports__.PromiseArray = PromiseArray;
12086
- __exports__.PromiseObject = PromiseObject;
11502
+ function setupRelationships(store, record, data) {
11503
+ var type = record.constructor;
11504
+
11505
+ type.eachRelationship(function(key, descriptor) {
11506
+ var kind = descriptor.kind;
11507
+ var value = data[key];
11508
+ var relationship = record._relationships[key];
11509
+
11510
+ if (data.links && data.links[key]) {
11511
+ relationship.updateLink(data.links[key]);
11512
+ }
12087
11513
 
11514
+ if (kind === 'belongsTo') {
11515
+ if (value === undefined) {
11516
+ return;
11517
+ }
11518
+ relationship.setRecord(value);
11519
+ } else if (kind === 'hasMany' && value) {
11520
+ relationship.updateRecordsFromAdapter(value);
11521
+ }
11522
+ });
11523
+ }
11524
+
11525
+ __exports__.Store = Store;
12088
11526
  __exports__["default"] = Store;
12089
11527
  });
12090
11528
  define("ember-data/transforms",