ember-data-source 1.0.0.beta.14.1 → 1.0.0.beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,13 +47,13 @@
47
47
  ```
48
48
 
49
49
  The `DS.InvalidError` must be constructed with a single object whose
50
- keys are the invalid model properties, and whose values are the
51
- corresponding error messages. For example:
50
+ keys are the invalid model properties, and whose values contain
51
+ arrays of the corresponding error messages. For example:
52
52
 
53
53
  ```javascript
54
54
  return new DS.InvalidError({
55
- length: 'Must be less than 15',
56
- name: 'Must not be blank'
55
+ length: ['Must be less than 15'],
56
+ name: ['Must not be blank']
57
57
  });
58
58
  ```
59
59
 
@@ -263,7 +263,7 @@
263
263
  the first parameter and the newly created record as the second parameter:
264
264
 
265
265
  ```javascript
266
- generateIdForRecord: function(store, record) {
266
+ generateIdForRecord: function(store, inputProperties) {
267
267
  var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
268
268
  return uuid;
269
269
  }
@@ -271,7 +271,8 @@
271
271
 
272
272
  @method generateIdForRecord
273
273
  @param {DS.Store} store
274
- @param {DS.Model} record
274
+ @param {Object} inputProperties a hash of properties to set on the
275
+ newly created record.
275
276
  @return {String|Number} id
276
277
  */
277
278
  generateIdForRecord: null,
@@ -298,7 +299,8 @@
298
299
  @return {Object} serialized record
299
300
  */
300
301
  serialize: function(record, options) {
301
- return ember$data$lib$system$adapter$$get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
302
+ var snapshot = record._createSnapshot();
303
+ return ember$data$lib$system$adapter$$get(record, 'store').serializerFor(snapshot.typeKey).serialize(snapshot, options);
302
304
  },
303
305
 
304
306
  /**
@@ -510,9 +512,9 @@
510
512
  fixturesForType: function(type) {
511
513
  if (type.FIXTURES) {
512
514
  var fixtures = Ember.A(type.FIXTURES);
513
- return fixtures.map(function(fixture){
515
+ return fixtures.map(function(fixture) {
514
516
  var fixtureIdType = typeof fixture.id;
515
- if(fixtureIdType !== "number" && fixtureIdType !== "string"){
517
+ if (fixtureIdType !== "number" && fixtureIdType !== "string") {
516
518
  throw new Error(ember$data$lib$adapters$fixture_adapter$$fmt('the id property must be defined as a number or string for fixture %@', [fixture]));
517
519
  }
518
520
  fixture.id = fixture.id + '';
@@ -541,7 +543,7 @@
541
543
  @param {Array} fixture
542
544
  */
543
545
  updateFixtures: function(type, fixture) {
544
- if(!type.FIXTURES) {
546
+ if (!type.FIXTURES) {
545
547
  type.FIXTURES = [];
546
548
  }
547
549
 
@@ -556,11 +558,13 @@
556
558
  Implement this method in order to provide json for CRUD methods
557
559
 
558
560
  @method mockJSON
561
+ @param {DS.Store} store
559
562
  @param {Subclass of DS.Model} type
560
563
  @param {DS.Model} record
561
564
  */
562
565
  mockJSON: function(store, type, record) {
563
- return store.serializerFor(type).serialize(record, { includeId: true });
566
+ var snapshot = record._createSnapshot();
567
+ return store.serializerFor(snapshot.typeKey).serialize(snapshot, { includeId: true });
564
568
  },
565
569
 
566
570
  /**
@@ -784,98 +788,78 @@
784
788
  }
785
789
  });
786
790
 
787
- /**
788
- * Polyfill Ember.Map behavior for Ember <= 1.7
789
- * This can probably be removed before 1.0 final
791
+ /*
792
+ The Map/MapWithDefault/OrderedSet code has been in flux as we try
793
+ to catch up with ES6. This is difficult as we support multiple
794
+ versions of Ember.
795
+ This file is currently here in case we have to polyfill ember's code
796
+ across a few releases. As ES6 comes to a close we should have a smaller
797
+ and smaller gap in implementations between Ember releases.
790
798
  */
791
- var ember$data$lib$system$map$$mapForEach, ember$data$lib$system$map$$deleteFn;
792
-
793
- function ember$data$lib$system$map$$OrderedSet(){
794
- Ember.OrderedSet.apply(this, arguments);
795
- }
796
-
797
- function ember$data$lib$system$map$$Map() {
798
- Ember.Map.apply(this, arguments);
799
- }
800
-
801
- function ember$data$lib$system$map$$MapWithDefault(){
802
- Ember.MapWithDefault.apply(this, arguments);
803
- }
804
-
805
- var ember$data$lib$system$map$$testMap = Ember.Map.create();
806
- ember$data$lib$system$map$$testMap.set('key', 'value');
799
+ var ember$data$lib$system$map$$Map = Ember.Map;
800
+ var ember$data$lib$system$map$$MapWithDefault = Ember.MapWithDefault;
801
+ var ember$data$lib$system$map$$OrderedSet = Ember.OrderedSet;
807
802
 
808
- var ember$data$lib$system$map$$usesOldBehavior = false;
809
-
810
- ember$data$lib$system$map$$testMap.forEach(function(value, key){
811
- ember$data$lib$system$map$$usesOldBehavior = value === 'key' && key === 'value';
812
- });
813
-
814
- ember$data$lib$system$map$$Map.prototype = Ember.create(Ember.Map.prototype);
815
- ember$data$lib$system$map$$MapWithDefault.prototype = Ember.create(Ember.MapWithDefault.prototype);
816
- ember$data$lib$system$map$$OrderedSet.prototype = Ember.create(Ember.OrderedSet.prototype);
803
+ var ember$data$lib$system$map$$default = ember$data$lib$system$map$$Map;
804
+ var ember$data$lib$adapters$rest_adapter$$get = Ember.get;
805
+ var ember$data$lib$adapters$rest_adapter$$forEach = Ember.ArrayPolyfills.forEach;
817
806
 
818
- ember$data$lib$system$map$$OrderedSet.create = function(){
819
- return new ember$data$lib$system$map$$OrderedSet();
820
- };
807
+ var ember$data$lib$adapters$rest_adapter$$default = ember$data$lib$system$adapter$$Adapter.extend({
808
+ defaultSerializer: '-rest',
821
809
 
822
- /**
823
- * returns a function that calls the original
824
- * callback function in the correct order.
825
- * if we are in pre-Ember.1.8 land, Map/MapWithDefault
826
- * forEach calls with key, value, in that order.
827
- * >= 1.8 forEach is called with the order value, key as per
828
- * the ES6 spec.
829
- */
830
- function ember$data$lib$system$map$$translate(valueKeyOrderedCallback){
831
- return function(key, value){
832
- valueKeyOrderedCallback.call(this, value, key);
833
- };
834
- }
810
+ /**
811
+ By default, the RESTAdapter will send the query params sorted alphabetically to the
812
+ server.
835
813
 
836
- // old, non ES6 compliant behavior
837
- if (ember$data$lib$system$map$$usesOldBehavior){
838
- ember$data$lib$system$map$$mapForEach = function(callback, thisArg){
839
- this.__super$forEach(ember$data$lib$system$map$$translate(callback), thisArg);
840
- };
814
+ For example:
841
815
 
842
- /* alias to remove */
843
- ember$data$lib$system$map$$deleteFn = function(thing){
844
- this.remove(thing);
845
- };
816
+ ```js
817
+ store.find('posts', {sort: 'price', category: 'pets'});
818
+ ```
846
819
 
847
- ember$data$lib$system$map$$Map.prototype.__super$forEach = Ember.Map.prototype.forEach;
848
- ember$data$lib$system$map$$Map.prototype.forEach = ember$data$lib$system$map$$mapForEach;
849
- ember$data$lib$system$map$$Map.prototype["delete"] = ember$data$lib$system$map$$deleteFn;
820
+ will generate a requests like this `/posts?category=pets&sort=price`, even if the
821
+ parameters were specified in a different order.
850
822
 
851
- ember$data$lib$system$map$$MapWithDefault.prototype.forEach = ember$data$lib$system$map$$mapForEach;
852
- ember$data$lib$system$map$$MapWithDefault.prototype.__super$forEach = Ember.MapWithDefault.prototype.forEach;
853
- ember$data$lib$system$map$$MapWithDefault.prototype["delete"] = ember$data$lib$system$map$$deleteFn;
823
+ That way the generated URL will be deterministic and that simplifies caching mechanisms
824
+ in the backend.
854
825
 
855
- ember$data$lib$system$map$$OrderedSet.prototype["delete"] = ember$data$lib$system$map$$deleteFn;
856
- }
826
+ Setting `sortQueryParams` to a falsey value will respect the original order.
857
827
 
858
- ember$data$lib$system$map$$MapWithDefault.constructor = ember$data$lib$system$map$$MapWithDefault;
859
- ember$data$lib$system$map$$Map.constructor = ember$data$lib$system$map$$Map;
828
+ In case you want to sort the query parameters with a different criteria, set
829
+ `sortQueryParams` to your custom sort function.
860
830
 
861
- ember$data$lib$system$map$$MapWithDefault.create = function(options){
862
- if (options) {
863
- return new ember$data$lib$system$map$$MapWithDefault(options);
864
- } else {
865
- return new ember$data$lib$system$map$$Map();
866
- }
867
- };
831
+ ```js
832
+ export default DS.RESTAdapter.extend({
833
+ sortQueryParams: function(params) {
834
+ var sortedKeys = Object.keys(params).sort().reverse();
835
+ var len = sortedKeys.length, newParams = {};
868
836
 
869
- ember$data$lib$system$map$$Map.create = function(){
870
- return new this.constructor();
871
- };
837
+ for (var i = 0; i < len; i++) {
838
+ newParams[sortedKeys[i]] = params[sortedKeys[i]];
839
+ }
840
+ return newParams;
841
+ }
842
+ });
843
+ ```
872
844
 
873
- var ember$data$lib$system$map$$default = ember$data$lib$system$map$$Map;
874
- var ember$data$lib$adapters$rest_adapter$$get = Ember.get;
875
- var ember$data$lib$adapters$rest_adapter$$forEach = Ember.ArrayPolyfills.forEach;
845
+ @method sortQueryParams
846
+ @param {Object} obj
847
+ @return {Object}
848
+ */
849
+ sortQueryParams: function(obj) {
850
+ var keys = Ember.keys(obj);
851
+ var len = keys.length;
852
+ if (len < 2) {
853
+ return obj;
854
+ }
855
+ var newQueryParams = {};
856
+ var sortedKeys = keys.sort();
876
857
 
877
- var ember$data$lib$adapters$rest_adapter$$default = ember$data$lib$system$adapter$$Adapter.extend({
878
- defaultSerializer: '-rest',
858
+ for (var i = 0; i < len; i++) {
859
+ newQueryParams[sortedKeys[i]] = obj[sortedKeys[i]];
860
+ }
861
+ return newQueryParams;
862
+ },
879
863
 
880
864
  /**
881
865
  By default the RESTAdapter will send each find request coming from a `store.find`
@@ -883,11 +867,14 @@
883
867
  ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests
884
868
  within a single runloop.
885
869
 
886
- For example, if you have an initial payload of
870
+ For example, if you have an initial payload of:
871
+
887
872
  ```javascript
888
- post: {
889
- id:1,
890
- comments: [1,2]
873
+ {
874
+ post: {
875
+ id: 1,
876
+ comments: [1, 2]
877
+ }
891
878
  }
892
879
  ```
893
880
 
@@ -1036,6 +1023,9 @@
1036
1023
  @return {Promise} promise
1037
1024
  */
1038
1025
  findQuery: function(store, type, query) {
1026
+ if (this.sortQueryParams) {
1027
+ query = this.sortQueryParams(query);
1028
+ }
1039
1029
  return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
1040
1030
  },
1041
1031
 
@@ -1171,7 +1161,8 @@
1171
1161
  var data = {};
1172
1162
  var serializer = store.serializerFor(type.typeKey);
1173
1163
 
1174
- serializer.serializeIntoHash(data, type, record, { includeId: true });
1164
+ var snapshot = record._createSnapshot();
1165
+ serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
1175
1166
 
1176
1167
  return this.ajax(this.buildURL(type.typeKey, null, record), "POST", { data: data });
1177
1168
  },
@@ -1196,7 +1187,8 @@
1196
1187
  var data = {};
1197
1188
  var serializer = store.serializerFor(type.typeKey);
1198
1189
 
1199
- serializer.serializeIntoHash(data, type, record);
1190
+ var snapshot = record._createSnapshot();
1191
+ serializer.serializeIntoHash(data, type, snapshot);
1200
1192
 
1201
1193
  var id = ember$data$lib$adapters$rest_adapter$$get(record, 'id');
1202
1194
 
@@ -1237,9 +1229,9 @@
1237
1229
  @return {String} url
1238
1230
  */
1239
1231
  buildURL: function(type, id, record) {
1240
- var url = [],
1241
- host = ember$data$lib$adapters$rest_adapter$$get(this, 'host'),
1242
- prefix = this.urlPrefix();
1232
+ var url = [];
1233
+ var host = ember$data$lib$adapters$rest_adapter$$get(this, 'host');
1234
+ var prefix = this.urlPrefix();
1243
1235
 
1244
1236
  if (type) { url.push(this.pathForType(type)); }
1245
1237
 
@@ -1269,8 +1261,15 @@
1269
1261
  var url = [];
1270
1262
 
1271
1263
  if (path) {
1264
+ // Protocol relative url
1265
+ //jscs:disable disallowEmptyBlocks
1266
+ if (/^\/\//.test(path)) {
1267
+ // Do nothing, the full host is already included. This branch
1268
+ // avoids the absolute path logic and the relative path logic.
1269
+
1272
1270
  // Absolute path
1273
- if (path.charAt(0) === '/') {
1271
+ } else if (path.charAt(0) === '/') {
1272
+ //jscs:enable disallowEmptyBlocks
1274
1273
  if (host) {
1275
1274
  path = path.slice(1);
1276
1275
  url.push(host);
@@ -1297,11 +1296,11 @@
1297
1296
 
1298
1297
  var expandedURL = url.split('/');
1299
1298
  //Case when the url is of the format ...something/:id
1300
- var lastSegment = expandedURL[ expandedURL.length - 1 ];
1299
+ var lastSegment = expandedURL[expandedURL.length - 1];
1301
1300
  var id = record.get('id');
1302
1301
  if (lastSegment === id) {
1303
1302
  expandedURL[expandedURL.length - 1] = "";
1304
- } else if(ember$data$lib$adapters$rest_adapter$$endsWith(lastSegment, '?id=' + id)) {
1303
+ } else if (ember$data$lib$adapters$rest_adapter$$endsWith(lastSegment, '?id=' + id)) {
1305
1304
  //Case when the url is of the format ...something?id=:id
1306
1305
  expandedURL[expandedURL.length - 1] = lastSegment.substring(0, lastSegment.length - id.length - 1);
1307
1306
  }
@@ -1309,9 +1308,7 @@
1309
1308
  return expandedURL.join('/');
1310
1309
  },
1311
1310
 
1312
- /**
1313
- http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
1314
- */
1311
+ // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
1315
1312
  maxUrlLength: 2048,
1316
1313
 
1317
1314
  /**
@@ -1337,11 +1334,11 @@
1337
1334
  loaded separately by `findMany`.
1338
1335
  */
1339
1336
  groupRecordsForFindMany: function (store, records) {
1340
- var groups = ember$data$lib$system$map$$MapWithDefault.create({defaultValue: function(){return [];}});
1337
+ var groups = ember$data$lib$system$map$$MapWithDefault.create({ defaultValue: function() { return []; } });
1341
1338
  var adapter = this;
1342
1339
  var maxUrlLength = this.maxUrlLength;
1343
1340
 
1344
- ember$data$lib$adapters$rest_adapter$$forEach.call(records, function(record){
1341
+ ember$data$lib$adapters$rest_adapter$$forEach.call(records, function(record) {
1345
1342
  var baseUrl = adapter._stripIDFromURL(store, record);
1346
1343
  groups.get(baseUrl).push(record);
1347
1344
  });
@@ -1368,7 +1365,7 @@
1368
1365
  }
1369
1366
 
1370
1367
  var groupsArray = [];
1371
- groups.forEach(function(group, key){
1368
+ groups.forEach(function(group, key) {
1372
1369
  var paramNameLength = '&ids%5B%5D='.length;
1373
1370
  var splitGroups = splitGroupToFitInUrl(group, maxUrlLength, paramNameLength);
1374
1371
 
@@ -1456,7 +1453,11 @@
1456
1453
  if (isObject) {
1457
1454
  jqXHR.then = null;
1458
1455
  if (!jqXHR.errorThrown) {
1459
- jqXHR.errorThrown = errorThrown;
1456
+ if (typeof errorThrown === 'string') {
1457
+ jqXHR.errorThrown = new Error(errorThrown);
1458
+ } else {
1459
+ jqXHR.errorThrown = errorThrown;
1460
+ }
1460
1461
  }
1461
1462
  }
1462
1463
 
@@ -1510,7 +1511,7 @@
1510
1511
  @private
1511
1512
  @param {String} url
1512
1513
  @param {String} type The request type GET, POST, PUT, DELETE etc.
1513
- @param {Object} hash
1514
+ @param {Object} options
1514
1515
  @return {Promise} promise
1515
1516
  */
1516
1517
  ajax: function(url, type, options) {
@@ -1541,8 +1542,8 @@
1541
1542
  @private
1542
1543
  @param {String} url
1543
1544
  @param {String} type The request type GET, POST, PUT, DELETE etc.
1544
- @param {Object} hash
1545
- @return {Object} hash
1545
+ @param {Object} options
1546
+ @return {Object}
1546
1547
  */
1547
1548
  ajaxOptions: function(url, type, options) {
1548
1549
  var hash = options || {};
@@ -1570,14 +1571,13 @@
1570
1571
  });
1571
1572
 
1572
1573
  //From http://stackoverflow.com/questions/280634/endswith-in-javascript
1573
- function ember$data$lib$adapters$rest_adapter$$endsWith(string, suffix){
1574
+ function ember$data$lib$adapters$rest_adapter$$endsWith(string, suffix) {
1574
1575
  if (typeof String.prototype.endsWith !== 'function') {
1575
1576
  return string.indexOf(suffix, string.length - suffix.length) !== -1;
1576
1577
  } else {
1577
1578
  return string.endsWith(suffix);
1578
1579
  }
1579
1580
  }
1580
-
1581
1581
  var ember$inflector$lib$system$inflector$$capitalize = Ember.String.capitalize;
1582
1582
 
1583
1583
  var ember$inflector$lib$system$inflector$$BLANK_REGEX = /^\s*$/;
@@ -2046,8 +2046,8 @@
2046
2046
  @module ember-data
2047
2047
  */
2048
2048
 
2049
- var activemodel$adapter$lib$system$active_model_adapter$$decamelize = Ember.String.decamelize,
2050
- activemodel$adapter$lib$system$active_model_adapter$$underscore = Ember.String.underscore;
2049
+ var activemodel$adapter$lib$system$active_model_adapter$$decamelize = Ember.String.decamelize;
2050
+ var activemodel$adapter$lib$system$active_model_adapter$$underscore = Ember.String.underscore;
2051
2051
 
2052
2052
  /**
2053
2053
  The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
@@ -2189,12 +2189,87 @@
2189
2189
  });
2190
2190
 
2191
2191
  var activemodel$adapter$lib$system$active_model_adapter$$default = activemodel$adapter$lib$system$active_model_adapter$$ActiveModelAdapter;
2192
+ /**
2193
+ @module ember-data
2194
+ */
2195
+
2196
+ /**
2197
+ `DS.Serializer` is an abstract base class that you should override in your
2198
+ application to customize it for your backend. The minimum set of methods
2199
+ that you should implement is:
2200
+
2201
+ * `extract()`
2202
+ * `serialize()`
2203
+
2204
+ And you can optionally override the following methods:
2205
+
2206
+ * `normalize()`
2207
+
2208
+ For an example implementation, see
2209
+ [DS.JSONSerializer](DS.JSONSerializer.html), the included JSON serializer.
2210
+
2211
+ @class Serializer
2212
+ @namespace DS
2213
+ @extends Ember.Object
2214
+ */
2215
+
2216
+ var ember$data$lib$system$serializer$$Serializer = Ember.Object.extend({
2217
+
2218
+ /**
2219
+ The `extract` method is used to deserialize the payload received from your
2220
+ data source into the form that Ember Data expects.
2221
+
2222
+ @method extract
2223
+ @param {DS.Store} store
2224
+ @param {subclass of DS.Model} type
2225
+ @param {Object} payload
2226
+ @param {String|Number} id
2227
+ @param {String} requestType
2228
+ @return {Object}
2229
+ */
2230
+ extract: Ember.required(Function),
2231
+
2232
+ /**
2233
+ The `serialize` method is used when a record is saved in order to convert
2234
+ the record into the form that your external data source expects.
2235
+
2236
+ `serialize` takes an optional `options` hash with a single option:
2237
+
2238
+ - `includeId`: If this is `true`, `serialize` should include the ID
2239
+ in the serialized object it builds.
2240
+
2241
+ @method serialize
2242
+ @param {subclass of DS.Model} record
2243
+ @param {Object} [options]
2244
+ @return {Object}
2245
+ */
2246
+ serialize: Ember.required(Function),
2247
+
2248
+ /**
2249
+ The `normalize` method is used to convert a payload received from your
2250
+ external data source into the normalized form `store.push()` expects. You
2251
+ should override this method, munge the hash and return the normalized
2252
+ payload.
2253
+
2254
+ @method normalize
2255
+ @param {subclass of DS.Model} type
2256
+ @param {Object} hash
2257
+ @return {Object}
2258
+ */
2259
+ normalize: function(type, hash) {
2260
+ return hash;
2261
+ }
2262
+
2263
+ });
2264
+
2265
+ var ember$data$lib$system$serializer$$default = ember$data$lib$system$serializer$$Serializer;
2266
+
2192
2267
  var ember$data$lib$serializers$json_serializer$$get = Ember.get;
2193
2268
  var ember$data$lib$serializers$json_serializer$$isNone = Ember.isNone;
2194
2269
  var ember$data$lib$serializers$json_serializer$$map = Ember.ArrayPolyfills.map;
2195
2270
  var ember$data$lib$serializers$json_serializer$$merge = Ember.merge;
2196
2271
 
2197
- var ember$data$lib$serializers$json_serializer$$default = Ember.Object.extend({
2272
+ var ember$data$lib$serializers$json_serializer$$default = ember$data$lib$system$serializer$$default.extend({
2198
2273
  /**
2199
2274
  The primaryKey is used when serializing and deserializing
2200
2275
  data. Ember Data always uses the `id` property to store the id of
@@ -2408,7 +2483,8 @@
2408
2483
  @private
2409
2484
  */
2410
2485
  normalizeUsingDeclaredMapping: function(type, hash) {
2411
- var attrs = ember$data$lib$serializers$json_serializer$$get(this, 'attrs'), payloadKey, key;
2486
+ var attrs = ember$data$lib$serializers$json_serializer$$get(this, 'attrs');
2487
+ var payloadKey, key;
2412
2488
 
2413
2489
  if (attrs) {
2414
2490
  for (key in attrs) {
@@ -2462,10 +2538,10 @@
2462
2538
  mappedKey = attrs[key];
2463
2539
  //We need to account for both the {title: 'post_title'} and
2464
2540
  //{title: {key: 'post_title'}} forms
2465
- if (mappedKey.key){
2541
+ if (mappedKey.key) {
2466
2542
  mappedKey = mappedKey.key;
2467
2543
  }
2468
- if (typeof mappedKey === 'string'){
2544
+ if (typeof mappedKey === 'string') {
2469
2545
  key = mappedKey;
2470
2546
  }
2471
2547
  }
@@ -2544,15 +2620,15 @@
2544
2620
 
2545
2621
  ```javascript
2546
2622
  App.PostSerializer = DS.JSONSerializer.extend({
2547
- serialize: function(post, options) {
2623
+ serialize: function(snapshot, options) {
2548
2624
  var json = {
2549
- POST_TTL: post.get('title'),
2550
- POST_BDY: post.get('body'),
2551
- POST_CMS: post.get('comments').mapBy('id')
2625
+ POST_TTL: snapshot.attr('title'),
2626
+ POST_BDY: snapshot.attr('body'),
2627
+ POST_CMS: snapshot.hasMany('comments', { ids: true })
2552
2628
  }
2553
2629
 
2554
2630
  if (options.includeId) {
2555
- json.POST_ID_ = post.get('id');
2631
+ json.POST_ID_ = snapshot.id;
2556
2632
  }
2557
2633
 
2558
2634
  return json;
@@ -2568,21 +2644,21 @@
2568
2644
 
2569
2645
  ```javascript
2570
2646
  App.ApplicationSerializer = DS.JSONSerializer.extend({
2571
- serialize: function(record, options) {
2647
+ serialize: function(snapshot, options) {
2572
2648
  var json = {};
2573
2649
 
2574
- record.eachAttribute(function(name) {
2575
- json[serverAttributeName(name)] = record.get(name);
2650
+ snapshot.eachAttribute(function(name) {
2651
+ json[serverAttributeName(name)] = snapshot.attr(name);
2576
2652
  })
2577
2653
 
2578
- record.eachRelationship(function(name, relationship) {
2654
+ snapshot.eachRelationship(function(name, relationship) {
2579
2655
  if (relationship.kind === 'hasMany') {
2580
- json[serverHasManyName(name)] = record.get(name).mapBy('id');
2656
+ json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
2581
2657
  }
2582
2658
  });
2583
2659
 
2584
2660
  if (options.includeId) {
2585
- json.ID_ = record.get('id');
2661
+ json.ID_ = snapshot.id;
2586
2662
  }
2587
2663
 
2588
2664
  return json;
@@ -2616,7 +2692,7 @@
2616
2692
 
2617
2693
  ```javascript
2618
2694
  App.PostSerializer = DS.JSONSerializer.extend({
2619
- serialize: function(record, options) {
2695
+ serialize: function(snapshot, options) {
2620
2696
  var json = this._super.apply(this, arguments);
2621
2697
 
2622
2698
  json.subject = json.title;
@@ -2628,30 +2704,30 @@
2628
2704
  ```
2629
2705
 
2630
2706
  @method serialize
2631
- @param {subclass of DS.Model} record
2707
+ @param {DS.Snapshot} snapshot
2632
2708
  @param {Object} options
2633
2709
  @return {Object} json
2634
2710
  */
2635
- serialize: function(record, options) {
2711
+ serialize: function(snapshot, options) {
2636
2712
  var json = {};
2637
2713
 
2638
2714
  if (options && options.includeId) {
2639
- var id = ember$data$lib$serializers$json_serializer$$get(record, 'id');
2715
+ var id = snapshot.id;
2640
2716
 
2641
2717
  if (id) {
2642
2718
  json[ember$data$lib$serializers$json_serializer$$get(this, 'primaryKey')] = id;
2643
2719
  }
2644
2720
  }
2645
2721
 
2646
- record.eachAttribute(function(key, attribute) {
2647
- this.serializeAttribute(record, json, key, attribute);
2722
+ snapshot.eachAttribute(function(key, attribute) {
2723
+ this.serializeAttribute(snapshot, json, key, attribute);
2648
2724
  }, this);
2649
2725
 
2650
- record.eachRelationship(function(key, relationship) {
2726
+ snapshot.eachRelationship(function(key, relationship) {
2651
2727
  if (relationship.kind === 'belongsTo') {
2652
- this.serializeBelongsTo(record, json, relationship);
2728
+ this.serializeBelongsTo(snapshot, json, relationship);
2653
2729
  } else if (relationship.kind === 'hasMany') {
2654
- this.serializeHasMany(record, json, relationship);
2730
+ this.serializeHasMany(snapshot, json, relationship);
2655
2731
  }
2656
2732
  }, this);
2657
2733
 
@@ -2669,9 +2745,9 @@
2669
2745
 
2670
2746
  ```js
2671
2747
  App.ApplicationSerializer = DS.RESTSerializer.extend({
2672
- serializeIntoHash: function(data, type, record, options) {
2748
+ serializeIntoHash: function(data, type, snapshot, options) {
2673
2749
  var root = Ember.String.decamelize(type.typeKey);
2674
- data[root] = this.serialize(record, options);
2750
+ data[root] = this.serialize(snapshot, options);
2675
2751
  }
2676
2752
  });
2677
2753
  ```
@@ -2679,11 +2755,11 @@
2679
2755
  @method serializeIntoHash
2680
2756
  @param {Object} hash
2681
2757
  @param {subclass of DS.Model} type
2682
- @param {DS.Model} record
2758
+ @param {DS.Snapshot} snapshot
2683
2759
  @param {Object} options
2684
2760
  */
2685
- serializeIntoHash: function(hash, type, record, options) {
2686
- ember$data$lib$serializers$json_serializer$$merge(hash, this.serialize(record, options));
2761
+ serializeIntoHash: function(hash, type, snapshot, options) {
2762
+ ember$data$lib$serializers$json_serializer$$merge(hash, this.serialize(snapshot, options));
2687
2763
  },
2688
2764
 
2689
2765
  /**
@@ -2696,24 +2772,24 @@
2696
2772
 
2697
2773
  ```javascript
2698
2774
  App.ApplicationSerializer = DS.JSONSerializer.extend({
2699
- serializeAttribute: function(record, json, key, attributes) {
2775
+ serializeAttribute: function(snapshot, json, key, attributes) {
2700
2776
  json.attributes = json.attributes || {};
2701
- this._super(record, json.attributes, key, attributes);
2777
+ this._super(snapshot, json.attributes, key, attributes);
2702
2778
  }
2703
2779
  });
2704
2780
  ```
2705
2781
 
2706
2782
  @method serializeAttribute
2707
- @param {DS.Model} record
2783
+ @param {DS.Snapshot} snapshot
2708
2784
  @param {Object} json
2709
2785
  @param {String} key
2710
2786
  @param {Object} attribute
2711
2787
  */
2712
- serializeAttribute: function(record, json, key, attribute) {
2788
+ serializeAttribute: function(snapshot, json, key, attribute) {
2713
2789
  var type = attribute.type;
2714
2790
 
2715
2791
  if (this._canSerialize(key)) {
2716
- var value = ember$data$lib$serializers$json_serializer$$get(record, key);
2792
+ var value = snapshot.attr(key);
2717
2793
  if (type) {
2718
2794
  var transform = this.transformFor(type);
2719
2795
  value = transform.serialize(value);
@@ -2739,28 +2815,28 @@
2739
2815
 
2740
2816
  ```javascript
2741
2817
  App.PostSerializer = DS.JSONSerializer.extend({
2742
- serializeBelongsTo: function(record, json, relationship) {
2818
+ serializeBelongsTo: function(snapshot, json, relationship) {
2743
2819
  var key = relationship.key;
2744
2820
 
2745
- var belongsTo = get(record, key);
2821
+ var belongsTo = snapshot.belongsTo(key);
2746
2822
 
2747
2823
  key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;
2748
2824
 
2749
- json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.toJSON();
2825
+ json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.record.toJSON();
2750
2826
  }
2751
2827
  });
2752
2828
  ```
2753
2829
 
2754
2830
  @method serializeBelongsTo
2755
- @param {DS.Model} record
2831
+ @param {DS.Snapshot} snapshot
2756
2832
  @param {Object} json
2757
2833
  @param {Object} relationship
2758
2834
  */
2759
- serializeBelongsTo: function(record, json, relationship) {
2835
+ serializeBelongsTo: function(snapshot, json, relationship) {
2760
2836
  var key = relationship.key;
2761
2837
 
2762
2838
  if (this._canSerialize(key)) {
2763
- var belongsTo = ember$data$lib$serializers$json_serializer$$get(record, key);
2839
+ var belongsToId = snapshot.belongsTo(key, { id: true });
2764
2840
 
2765
2841
  // if provided, use the mapping provided by `attrs` in
2766
2842
  // the serializer
@@ -2770,14 +2846,14 @@
2770
2846
  }
2771
2847
 
2772
2848
  //Need to check whether the id is there for new&async records
2773
- if (ember$data$lib$serializers$json_serializer$$isNone(belongsTo) || ember$data$lib$serializers$json_serializer$$isNone(ember$data$lib$serializers$json_serializer$$get(belongsTo, 'id'))) {
2849
+ if (ember$data$lib$serializers$json_serializer$$isNone(belongsToId)) {
2774
2850
  json[payloadKey] = null;
2775
2851
  } else {
2776
- json[payloadKey] = ember$data$lib$serializers$json_serializer$$get(belongsTo, 'id');
2852
+ json[payloadKey] = belongsToId;
2777
2853
  }
2778
2854
 
2779
2855
  if (relationship.options.polymorphic) {
2780
- this.serializePolymorphicType(record, json, relationship);
2856
+ this.serializePolymorphicType(snapshot, json, relationship);
2781
2857
  }
2782
2858
  }
2783
2859
  },
@@ -2790,7 +2866,7 @@
2790
2866
 
2791
2867
  ```javascript
2792
2868
  App.PostSerializer = DS.JSONSerializer.extend({
2793
- serializeHasMany: function(record, json, relationship) {
2869
+ serializeHasMany: function(snapshot, json, relationship) {
2794
2870
  var key = relationship.key;
2795
2871
  if (key === 'comments') {
2796
2872
  return;
@@ -2802,11 +2878,11 @@
2802
2878
  ```
2803
2879
 
2804
2880
  @method serializeHasMany
2805
- @param {DS.Model} record
2881
+ @param {DS.Snapshot} snapshot
2806
2882
  @param {Object} json
2807
2883
  @param {Object} relationship
2808
2884
  */
2809
- serializeHasMany: function(record, json, relationship) {
2885
+ serializeHasMany: function(snapshot, json, relationship) {
2810
2886
  var key = relationship.key;
2811
2887
 
2812
2888
  if (this._canSerialize(key)) {
@@ -2819,10 +2895,10 @@
2819
2895
  payloadKey = this.keyForRelationship(key, "hasMany");
2820
2896
  }
2821
2897
 
2822
- var relationshipType = record.constructor.determineRelationshipType(relationship);
2898
+ var relationshipType = snapshot.type.determineRelationshipType(relationship);
2823
2899
 
2824
2900
  if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') {
2825
- json[payloadKey] = ember$data$lib$serializers$json_serializer$$get(record, key).mapBy('id');
2901
+ json[payloadKey] = snapshot.hasMany(key, { ids: true });
2826
2902
  // TODO support for polymorphic manyToNone and manyToMany relationships
2827
2903
  }
2828
2904
  }
@@ -2838,22 +2914,22 @@
2838
2914
 
2839
2915
  ```javascript
2840
2916
  App.CommentSerializer = DS.JSONSerializer.extend({
2841
- serializePolymorphicType: function(record, json, relationship) {
2917
+ serializePolymorphicType: function(snapshot, json, relationship) {
2842
2918
  var key = relationship.key,
2843
- belongsTo = get(record, key);
2919
+ belongsTo = snapshot.belongsTo(key);
2844
2920
  key = this.keyForAttribute ? this.keyForAttribute(key) : key;
2845
2921
 
2846
2922
  if (Ember.isNone(belongsTo)) {
2847
2923
  json[key + "_type"] = null;
2848
2924
  } else {
2849
- json[key + "_type"] = belongsTo.constructor.typeKey;
2925
+ json[key + "_type"] = belongsTo.typeKey;
2850
2926
  }
2851
2927
  }
2852
2928
  });
2853
2929
  ```
2854
2930
 
2855
2931
  @method serializePolymorphicType
2856
- @param {DS.Model} record
2932
+ @param {DS.Snapshot} snapshot
2857
2933
  @param {Object} json
2858
2934
  @param {Object} relationship
2859
2935
  */
@@ -2871,17 +2947,20 @@
2871
2947
  This method delegates to a more specific extract method based on
2872
2948
  the `requestType`.
2873
2949
 
2874
- Example
2950
+ To override this method with a custom one, make sure to call
2951
+ `this._super(store, type, payload, id, requestType)` with your
2952
+ pre-processed data.
2953
+
2954
+ Here's an example of using `extract` manually:
2875
2955
 
2876
2956
  ```javascript
2877
- var get = Ember.get;
2878
2957
  socket.on('message', function(message) {
2879
- var modelName = message.model;
2880
2958
  var data = message.data;
2881
- var type = store.modelFor(modelName);
2959
+ var type = store.modelFor(message.modelName);
2882
2960
  var serializer = store.serializerFor(type.typeKey);
2883
- var record = serializer.extract(store, type, data, get(data, 'id'), 'single');
2884
- store.push(modelName, record);
2961
+ var record = serializer.extract(store, type, data, data.id, 'single');
2962
+
2963
+ store.push(message.modelName, record);
2885
2964
  });
2886
2965
  ```
2887
2966
 
@@ -2913,7 +2992,7 @@
2913
2992
  @param {String} requestType
2914
2993
  @return {Array} array An array of deserialized objects
2915
2994
  */
2916
- extractFindAll: function(store, type, payload, id, requestType){
2995
+ extractFindAll: function(store, type, payload, id, requestType) {
2917
2996
  return this.extractArray(store, type, payload, id, requestType);
2918
2997
  },
2919
2998
  /**
@@ -2929,7 +3008,7 @@
2929
3008
  @param {String} requestType
2930
3009
  @return {Array} array An array of deserialized objects
2931
3010
  */
2932
- extractFindQuery: function(store, type, payload, id, requestType){
3011
+ extractFindQuery: function(store, type, payload, id, requestType) {
2933
3012
  return this.extractArray(store, type, payload, id, requestType);
2934
3013
  },
2935
3014
  /**
@@ -2945,7 +3024,7 @@
2945
3024
  @param {String} requestType
2946
3025
  @return {Array} array An array of deserialized objects
2947
3026
  */
2948
- extractFindMany: function(store, type, payload, id, requestType){
3027
+ extractFindMany: function(store, type, payload, id, requestType) {
2949
3028
  return this.extractArray(store, type, payload, id, requestType);
2950
3029
  },
2951
3030
  /**
@@ -2961,7 +3040,7 @@
2961
3040
  @param {String} requestType
2962
3041
  @return {Array} array An array of deserialized objects
2963
3042
  */
2964
- extractFindHasMany: function(store, type, payload, id, requestType){
3043
+ extractFindHasMany: function(store, type, payload, id, requestType) {
2965
3044
  return this.extractArray(store, type, payload, id, requestType);
2966
3045
  },
2967
3046
 
@@ -3158,7 +3237,7 @@
3158
3237
 
3159
3238
  /**
3160
3239
  `extractErrors` is used to extract model errors when a call is made
3161
- to `DS.Model#save` which fails with an InvalidError`. By default
3240
+ to `DS.Model#save` which fails with an `InvalidError`. By default
3162
3241
  Ember Data expects error information to be located on the `errors`
3163
3242
  property of the payload object.
3164
3243
 
@@ -3209,7 +3288,7 @@
3209
3288
  @param {String} key
3210
3289
  @return {String} normalized key
3211
3290
  */
3212
- keyForAttribute: function(key){
3291
+ keyForAttribute: function(key) {
3213
3292
  return key;
3214
3293
  },
3215
3294
 
@@ -3234,7 +3313,7 @@
3234
3313
  @return {String} normalized key
3235
3314
  */
3236
3315
 
3237
- keyForRelationship: function(key, type){
3316
+ keyForRelationship: function(key, type) {
3238
3317
  return key;
3239
3318
  },
3240
3319
 
@@ -3254,7 +3333,6 @@
3254
3333
  }
3255
3334
  });
3256
3335
 
3257
- var ember$data$lib$serializers$rest_serializer$$get = Ember.get;
3258
3336
  var ember$data$lib$serializers$rest_serializer$$forEach = Ember.ArrayPolyfills.forEach;
3259
3337
  var ember$data$lib$serializers$rest_serializer$$map = Ember.ArrayPolyfills.map;
3260
3338
  var ember$data$lib$serializers$rest_serializer$$camelize = Ember.String.camelize;
@@ -3517,7 +3595,7 @@
3517
3595
  for (var prop in payload) {
3518
3596
  var typeName = this.typeForRoot(prop);
3519
3597
 
3520
- if (!store.modelFactoryFor(typeName)){
3598
+ if (!store.modelFactoryFor(typeName)) {
3521
3599
  Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
3522
3600
  continue;
3523
3601
  }
@@ -3737,7 +3815,7 @@
3737
3815
 
3738
3816
  for (var prop in payload) {
3739
3817
  var typeName = this.typeForRoot(prop);
3740
- if (!store.modelFactoryFor(typeName, prop)){
3818
+ if (!store.modelFactoryFor(typeName, prop)) {
3741
3819
  Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
3742
3820
  continue;
3743
3821
  }
@@ -3857,15 +3935,15 @@
3857
3935
 
3858
3936
  ```js
3859
3937
  App.PostSerializer = DS.RESTSerializer.extend({
3860
- serialize: function(post, options) {
3938
+ serialize: function(snapshot, options) {
3861
3939
  var json = {
3862
- POST_TTL: post.get('title'),
3863
- POST_BDY: post.get('body'),
3864
- POST_CMS: post.get('comments').mapBy('id')
3940
+ POST_TTL: snapshot.attr('title'),
3941
+ POST_BDY: snapshot.attr('body'),
3942
+ POST_CMS: snapshot.hasMany('comments', { ids: true })
3865
3943
  }
3866
3944
 
3867
3945
  if (options.includeId) {
3868
- json.POST_ID_ = post.get('id');
3946
+ json.POST_ID_ = snapshot.id;
3869
3947
  }
3870
3948
 
3871
3949
  return json;
@@ -3881,21 +3959,21 @@
3881
3959
 
3882
3960
  ```js
3883
3961
  App.ApplicationSerializer = DS.RESTSerializer.extend({
3884
- serialize: function(record, options) {
3962
+ serialize: function(snapshot, options) {
3885
3963
  var json = {};
3886
3964
 
3887
- record.eachAttribute(function(name) {
3888
- json[serverAttributeName(name)] = record.get(name);
3965
+ snapshot.eachAttribute(function(name) {
3966
+ json[serverAttributeName(name)] = snapshot.attr(name);
3889
3967
  })
3890
3968
 
3891
- record.eachRelationship(function(name, relationship) {
3969
+ snapshot.eachRelationship(function(name, relationship) {
3892
3970
  if (relationship.kind === 'hasMany') {
3893
- json[serverHasManyName(name)] = record.get(name).mapBy('id');
3971
+ json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
3894
3972
  }
3895
3973
  });
3896
3974
 
3897
3975
  if (options.includeId) {
3898
- json.ID_ = record.get('id');
3976
+ json.ID_ = snapshot.id;
3899
3977
  }
3900
3978
 
3901
3979
  return json;
@@ -3929,8 +4007,8 @@
3929
4007
 
3930
4008
  ```js
3931
4009
  App.PostSerializer = DS.RESTSerializer.extend({
3932
- serialize: function(record, options) {
3933
- var json = this._super(record, options);
4010
+ serialize: function(snapshot, options) {
4011
+ var json = this._super(snapshot, options);
3934
4012
 
3935
4013
  json.subject = json.title;
3936
4014
  delete json.title;
@@ -3941,11 +4019,11 @@
3941
4019
  ```
3942
4020
 
3943
4021
  @method serialize
3944
- @param {subclass of DS.Model} record
4022
+ @param {DS.Snapshot} snapshot
3945
4023
  @param {Object} options
3946
4024
  @return {Object} json
3947
4025
  */
3948
- serialize: function(record, options) {
4026
+ serialize: function(snapshot, options) {
3949
4027
  return this._super.apply(this, arguments);
3950
4028
  },
3951
4029
 
@@ -3968,11 +4046,11 @@
3968
4046
  @method serializeIntoHash
3969
4047
  @param {Object} hash
3970
4048
  @param {subclass of DS.Model} type
3971
- @param {DS.Model} record
4049
+ @param {DS.Snapshot} snapshot
3972
4050
  @param {Object} options
3973
4051
  */
3974
- serializeIntoHash: function(hash, type, record, options) {
3975
- hash[type.typeKey] = this.serialize(record, options);
4052
+ serializeIntoHash: function(hash, type, snapshot, options) {
4053
+ hash[type.typeKey] = this.serialize(snapshot, options);
3976
4054
  },
3977
4055
 
3978
4056
  /**
@@ -3981,25 +4059,25 @@
3981
4059
  the attribute and value from the model's camelcased model name.
3982
4060
 
3983
4061
  @method serializePolymorphicType
3984
- @param {DS.Model} record
4062
+ @param {DS.Snapshot} snapshot
3985
4063
  @param {Object} json
3986
4064
  @param {Object} relationship
3987
4065
  */
3988
- serializePolymorphicType: function(record, json, relationship) {
4066
+ serializePolymorphicType: function(snapshot, json, relationship) {
3989
4067
  var key = relationship.key;
3990
- var belongsTo = ember$data$lib$serializers$rest_serializer$$get(record, key);
4068
+ var belongsTo = snapshot.belongsTo(key);
3991
4069
  key = this.keyForAttribute ? this.keyForAttribute(key) : key;
3992
4070
  if (Ember.isNone(belongsTo)) {
3993
4071
  json[key + "Type"] = null;
3994
4072
  } else {
3995
- json[key + "Type"] = Ember.String.camelize(belongsTo.constructor.typeKey);
4073
+ json[key + "Type"] = Ember.String.camelize(belongsTo.typeKey);
3996
4074
  }
3997
4075
  }
3998
4076
  });
3999
4077
 
4000
- Ember.runInDebug(function(){
4078
+ Ember.runInDebug(function() {
4001
4079
  ember$data$lib$serializers$rest_serializer$$RESTSerializer.reopen({
4002
- warnMessageNoModelForKey: function(prop, typeKey){
4080
+ warnMessageNoModelForKey: function(prop, typeKey) {
4003
4081
  return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + typeKey + '" (resolved model name using ' + this.constructor.toString() + '.typeForRoot("' + prop + '"))';
4004
4082
  }
4005
4083
  });
@@ -4010,12 +4088,12 @@
4010
4088
  @module ember-data
4011
4089
  */
4012
4090
 
4013
- var activemodel$adapter$lib$system$active_model_serializer$$get = Ember.get,
4014
- activemodel$adapter$lib$system$active_model_serializer$$forEach = Ember.EnumerableUtils.forEach,
4015
- activemodel$adapter$lib$system$active_model_serializer$$camelize = Ember.String.camelize,
4016
- activemodel$adapter$lib$system$active_model_serializer$$capitalize = Ember.String.capitalize,
4017
- activemodel$adapter$lib$system$active_model_serializer$$decamelize = Ember.String.decamelize,
4018
- activemodel$adapter$lib$system$active_model_serializer$$underscore = Ember.String.underscore;
4091
+ var activemodel$adapter$lib$system$active_model_serializer$$forEach = Ember.EnumerableUtils.forEach;
4092
+ var activemodel$adapter$lib$system$active_model_serializer$$camelize = Ember.String.camelize;
4093
+ var activemodel$adapter$lib$system$active_model_serializer$$capitalize = Ember.String.capitalize;
4094
+ var activemodel$adapter$lib$system$active_model_serializer$$decamelize = Ember.String.decamelize;
4095
+ var activemodel$adapter$lib$system$active_model_serializer$$underscore = Ember.String.underscore;
4096
+
4019
4097
  /**
4020
4098
  The ActiveModelSerializer is a subclass of the RESTSerializer designed to integrate
4021
4099
  with a JSON API that uses an underscored naming convention instead of camelCasing.
@@ -4148,31 +4226,31 @@
4148
4226
  @method serializeIntoHash
4149
4227
  @param {Object} hash
4150
4228
  @param {subclass of DS.Model} type
4151
- @param {DS.Model} record
4229
+ @param {DS.Snapshot} snapshot
4152
4230
  @param {Object} options
4153
4231
  */
4154
- serializeIntoHash: function(data, type, record, options) {
4232
+ serializeIntoHash: function(data, type, snapshot, options) {
4155
4233
  var root = activemodel$adapter$lib$system$active_model_serializer$$underscore(activemodel$adapter$lib$system$active_model_serializer$$decamelize(type.typeKey));
4156
- data[root] = this.serialize(record, options);
4234
+ data[root] = this.serialize(snapshot, options);
4157
4235
  },
4158
4236
 
4159
4237
  /**
4160
4238
  Serializes a polymorphic type as a fully capitalized model name.
4161
4239
 
4162
4240
  @method serializePolymorphicType
4163
- @param {DS.Model} record
4241
+ @param {DS.Snapshot} snapshot
4164
4242
  @param {Object} json
4165
4243
  @param {Object} relationship
4166
4244
  */
4167
- serializePolymorphicType: function(record, json, relationship) {
4245
+ serializePolymorphicType: function(snapshot, json, relationship) {
4168
4246
  var key = relationship.key;
4169
- var belongsTo = activemodel$adapter$lib$system$active_model_serializer$$get(record, key);
4247
+ var belongsTo = snapshot.belongsTo(key);
4170
4248
  var jsonKey = activemodel$adapter$lib$system$active_model_serializer$$underscore(key + "_type");
4171
4249
 
4172
4250
  if (Ember.isNone(belongsTo)) {
4173
4251
  json[jsonKey] = null;
4174
4252
  } else {
4175
- json[jsonKey] = activemodel$adapter$lib$system$active_model_serializer$$capitalize(activemodel$adapter$lib$system$active_model_serializer$$camelize(belongsTo.constructor.typeKey));
4253
+ json[jsonKey] = activemodel$adapter$lib$system$active_model_serializer$$capitalize(activemodel$adapter$lib$system$active_model_serializer$$camelize(belongsTo.typeKey));
4176
4254
  }
4177
4255
  },
4178
4256
 
@@ -4225,7 +4303,7 @@
4225
4303
  @param {Object} data
4226
4304
  */
4227
4305
 
4228
- normalizeLinks: function(data){
4306
+ normalizeLinks: function(data) {
4229
4307
  if (data.links) {
4230
4308
  var links = data.links;
4231
4309
 
@@ -4303,18 +4381,20 @@
4303
4381
  @namespace DS
4304
4382
  @private
4305
4383
  */
4306
- function ember$data$lib$system$container_proxy$$ContainerProxy(container){
4384
+ function ember$data$lib$system$container_proxy$$ContainerProxy(container) {
4307
4385
  this.container = container;
4308
4386
  }
4309
4387
 
4310
4388
  ember$data$lib$system$container_proxy$$ContainerProxy.prototype.aliasedFactory = function(path, preLookup) {
4311
4389
  var _this = this;
4312
4390
 
4313
- return {create: function(){
4314
- if (preLookup) { preLookup(); }
4391
+ return {
4392
+ create: function() {
4393
+ if (preLookup) { preLookup(); }
4315
4394
 
4316
- return _this.container.lookup(path);
4317
- }};
4395
+ return _this.container.lookup(path);
4396
+ }
4397
+ };
4318
4398
  };
4319
4399
 
4320
4400
  ember$data$lib$system$container_proxy$$ContainerProxy.prototype.registerAlias = function(source, dest, preLookup) {
@@ -4324,7 +4404,7 @@
4324
4404
  };
4325
4405
 
4326
4406
  ember$data$lib$system$container_proxy$$ContainerProxy.prototype.registerDeprecation = function(deprecated, valid) {
4327
- var preLookupCallback = function(){
4407
+ var preLookupCallback = function() {
4328
4408
  Ember.deprecate("You tried to look up '" + deprecated + "', " +
4329
4409
  "but this has been deprecated in favor of '" + valid + "'.", false);
4330
4410
  };
@@ -4345,7 +4425,7 @@
4345
4425
  };
4346
4426
 
4347
4427
  var ember$data$lib$system$container_proxy$$default = ember$data$lib$system$container_proxy$$ContainerProxy;
4348
- function activemodel$adapter$lib$setup$container$$setupActiveModelAdapter(container, application){
4428
+ function activemodel$adapter$lib$setup$container$$setupActiveModelAdapter(container, application) {
4349
4429
  var proxy = new ember$data$lib$system$container_proxy$$default(container);
4350
4430
  proxy.registerDeprecations([
4351
4431
  { deprecated: 'serializer:_ams', valid: 'serializer:-active-model' },
@@ -4370,12 +4450,12 @@
4370
4450
  /**
4371
4451
  @property VERSION
4372
4452
  @type String
4373
- @default '1.0.0-beta.14.1'
4453
+ @default '1.0.0-beta.15'
4374
4454
  @static
4375
4455
  */
4376
4456
  /*jshint -W079 */
4377
4457
  var ember$data$lib$core$$DS = Ember.Namespace.create({
4378
- VERSION: '1.0.0-beta.14.1'
4458
+ VERSION: '1.0.0-beta.15'
4379
4459
  });
4380
4460
 
4381
4461
  if (Ember.libraries) {
@@ -4628,22 +4708,26 @@
4628
4708
  var content = ember$data$lib$system$record_arrays$record_array$$get(this, 'content');
4629
4709
  if (idx === undefined) {
4630
4710
  content.addObject(record);
4631
- } else {
4632
- if (!content.contains(record)) {
4633
- content.insertAt(idx, record);
4634
- }
4711
+ } else if (!content.contains(record)) {
4712
+ content.insertAt(idx, record);
4635
4713
  }
4636
4714
  },
4637
4715
 
4716
+ _pushRecord: function(record) {
4717
+ ember$data$lib$system$record_arrays$record_array$$get(this, 'content').pushObject(record);
4718
+ },
4719
+
4638
4720
  /**
4639
4721
  Adds a record to the `RecordArray`, but allows duplicates
4640
4722
 
4723
+ @deprecated
4641
4724
  @method pushRecord
4642
4725
  @private
4643
4726
  @param {DS.Model} record
4644
4727
  */
4645
4728
  pushRecord: function(record) {
4646
- ember$data$lib$system$record_arrays$record_array$$get(this, 'content').pushObject(record);
4729
+ Ember.deprecate('Usage of `recordArray.pushRecord` is deprecated, use `recordArray.addObject` instead');
4730
+ this._pushRecord(record);
4647
4731
  },
4648
4732
  /**
4649
4733
  Removes a record to the `RecordArray`.
@@ -4673,10 +4757,11 @@
4673
4757
  @return {DS.PromiseArray} promise
4674
4758
  */
4675
4759
  save: function() {
4760
+ var recordArray = this;
4676
4761
  var promiseLabel = "DS: RecordArray#save " + ember$data$lib$system$record_arrays$record_array$$get(this, 'type');
4677
4762
  var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) {
4678
- return Ember.A(array);
4679
- }, null, "DS: RecordArray#save apply Ember.NativeArray");
4763
+ return recordArray;
4764
+ }, null, "DS: RecordArray#save return RecordArray");
4680
4765
 
4681
4766
  return ember$data$lib$system$promise_proxies$$PromiseArray.create({ promise: promise });
4682
4767
  },
@@ -4684,7 +4769,7 @@
4684
4769
  _dissociateFromOwnRecords: function() {
4685
4770
  var array = this;
4686
4771
 
4687
- this.forEach(function(record){
4772
+ this.forEach(function(record) {
4688
4773
  var recordArrays = record._recordArrays;
4689
4774
 
4690
4775
  if (recordArrays) {
@@ -4697,7 +4782,7 @@
4697
4782
  @method _unregisterFromManager
4698
4783
  @private
4699
4784
  */
4700
- _unregisterFromManager: function(){
4785
+ _unregisterFromManager: function() {
4701
4786
  var manager = ember$data$lib$system$record_arrays$record_array$$get(this, 'manager');
4702
4787
  //We will stop needing this stupid if statement soon, once manyArray are refactored to not be RecordArrays
4703
4788
  if (manager) {
@@ -4705,11 +4790,11 @@
4705
4790
  }
4706
4791
  },
4707
4792
 
4708
- willDestroy: function(){
4793
+ willDestroy: function() {
4709
4794
  this._unregisterFromManager();
4710
4795
  this._dissociateFromOwnRecords();
4711
4796
  ember$data$lib$system$record_arrays$record_array$$set(this, 'content', undefined);
4712
- this._super();
4797
+ this._super.apply(this, arguments);
4713
4798
  }
4714
4799
  });
4715
4800
 
@@ -4765,8 +4850,7 @@
4765
4850
 
4766
4851
  updateFilter: Ember.observer(function() {
4767
4852
  Ember.run.once(this, this._updateFilter);
4768
- }, 'filterFunction'),
4769
-
4853
+ }, 'filterFunction')
4770
4854
  });
4771
4855
 
4772
4856
  /**
@@ -4817,16 +4901,12 @@
4817
4901
  }
4818
4902
  });
4819
4903
 
4820
- /**
4821
- @module ember-data
4822
- */
4823
-
4824
- var ember$data$lib$system$record_arrays$many_array$$get = Ember.get, ember$data$lib$system$record_arrays$many_array$$set = Ember.set;
4904
+ var ember$data$lib$system$record_arrays$many_array$$get = Ember.get;
4905
+ var ember$data$lib$system$record_arrays$many_array$$set = Ember.set;
4825
4906
 
4826
4907
  var ember$data$lib$system$record_arrays$many_array$$default = Ember.Object.extend(Ember.MutableArray, Ember.Evented, {
4827
4908
  init: function() {
4828
4909
  this.currentState = Ember.A([]);
4829
- this.diff = [];
4830
4910
  },
4831
4911
 
4832
4912
  record: null,
@@ -4834,8 +4914,6 @@
4834
4914
  canonicalState: null,
4835
4915
  currentState: null,
4836
4916
 
4837
- diff: null,
4838
-
4839
4917
  length: 0,
4840
4918
 
4841
4919
  objectAt: function(index) {
@@ -4855,10 +4933,11 @@
4855
4933
  return record.get('isNew');
4856
4934
  });
4857
4935
  toSet = toSet.concat(newRecords);
4858
- this.arrayContentWillChange(0, this.length, this.length);
4936
+ var oldLength = this.length;
4937
+ this.arrayContentWillChange(0, this.length, toSet.length);
4859
4938
  this.set('length', toSet.length);
4860
4939
  this.currentState = toSet;
4861
- this.arrayContentDidChange(0, this.length, this.length);
4940
+ this.arrayContentDidChange(0, oldLength, this.length);
4862
4941
  //TODO Figure out to notify only on additions and maybe only if unloaded
4863
4942
  this.relationship.notifyHasManyChanged();
4864
4943
  this.record.updateRecordArrays();
@@ -4894,7 +4973,7 @@
4894
4973
  this.currentState.splice.apply(this.currentState, [idx, amt].concat(objects));
4895
4974
  this.set('length', this.currentState.length);
4896
4975
  this.arrayContentDidChange(idx, amt, objects.length);
4897
- if (objects){
4976
+ if (objects) {
4898
4977
  //TODO(Igor) probably needed only for unloaded records
4899
4978
  this.relationship.notifyHasManyChanged();
4900
4979
  }
@@ -4904,7 +4983,7 @@
4904
4983
  //TODO(Igor) optimize
4905
4984
  internalRemoveRecords: function(records) {
4906
4985
  var index;
4907
- for(var i=0; i < records.length; i++) {
4986
+ for (var i=0; i < records.length; i++) {
4908
4987
  index = this.currentState.indexOf(records[i]);
4909
4988
  this.internalReplace(index, 1);
4910
4989
  }
@@ -4920,11 +4999,11 @@
4920
4999
 
4921
5000
  replace: function(idx, amt, objects) {
4922
5001
  var records;
4923
- if (amt > 0){
5002
+ if (amt > 0) {
4924
5003
  records = this.currentState.slice(idx, idx+amt);
4925
5004
  this.get('relationship').removeRecords(records);
4926
5005
  }
4927
- if (objects){
5006
+ if (objects) {
4928
5007
  this.get('relationship').addRecords(objects, idx);
4929
5008
  }
4930
5009
  },
@@ -4966,6 +5045,35 @@
4966
5045
  return this.relationship.reload();
4967
5046
  },
4968
5047
 
5048
+ /**
5049
+ Saves all of the records in the `ManyArray`.
5050
+
5051
+ Example
5052
+
5053
+ ```javascript
5054
+ store.find('inbox', 1).then(function(inbox) {
5055
+ inbox.get('messages').then(function(messages) {
5056
+ messages.forEach(function(message) {
5057
+ message.set('isRead', true);
5058
+ });
5059
+ messages.save()
5060
+ });
5061
+ });
5062
+ ```
5063
+
5064
+ @method save
5065
+ @return {DS.PromiseArray} promise
5066
+ */
5067
+ save: function() {
5068
+ var manyArray = this;
5069
+ var promiseLabel = "DS: ManyArray#save " + ember$data$lib$system$record_arrays$many_array$$get(this, 'type');
5070
+ var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) {
5071
+ return manyArray;
5072
+ }, null, "DS: ManyArray#save return ManyArray");
5073
+
5074
+ return ember$data$lib$system$promise_proxies$$PromiseArray.create({ promise: promise });
5075
+ },
5076
+
4969
5077
  /**
4970
5078
  Create a child record within the owner
4971
5079
 
@@ -4985,6 +5093,26 @@
4985
5093
  this.pushObject(record);
4986
5094
 
4987
5095
  return record;
5096
+ },
5097
+
5098
+ /**
5099
+ @method addRecord
5100
+ @param {DS.Model} record
5101
+ @deprecated Use `addObject()` instead
5102
+ */
5103
+ addRecord: function(record) {
5104
+ Ember.deprecate('Using manyArray.addRecord() has been deprecated. You should use manyArray.addObject() instead.');
5105
+ this.addObject(record);
5106
+ },
5107
+
5108
+ /**
5109
+ @method removeRecord
5110
+ @param {DS.Model} record
5111
+ @deprecated Use `removeObject()` instead
5112
+ */
5113
+ removeRecord: function(record) {
5114
+ Ember.deprecate('Using manyArray.removeRecord() has been deprecated. You should use manyArray.removeObject() instead.');
5115
+ this.removeObject(record);
4988
5116
  }
4989
5117
  });
4990
5118
 
@@ -5042,13 +5170,15 @@
5042
5170
 
5043
5171
  if (!recordArrays) { return; }
5044
5172
 
5045
- recordArrays.forEach(function(array){
5173
+ recordArrays.forEach(function(array) {
5046
5174
  array.removeRecord(record);
5047
5175
  });
5048
5176
 
5049
5177
  record._recordArrays = null;
5050
5178
  },
5051
5179
 
5180
+
5181
+ //Don't need to update non filtered arrays on simple changes
5052
5182
  _recordWasChanged: function (record) {
5053
5183
  var type = record.constructor;
5054
5184
  var recordArrays = this.filteredRecordArrays.get(type);
@@ -5056,22 +5186,23 @@
5056
5186
 
5057
5187
  ember$data$lib$system$record_array_manager$$forEach(recordArrays, function(array) {
5058
5188
  filter = ember$data$lib$system$record_array_manager$$get(array, 'filterFunction');
5059
- this.updateRecordArray(array, filter, type, record);
5189
+ if (filter) {
5190
+ this.updateRecordArray(array, filter, type, record);
5191
+ }
5060
5192
  }, this);
5193
+ },
5061
5194
 
5062
- // loop through all manyArrays containing an unloaded copy of this
5063
- // clientId and notify them that the record was loaded.
5064
- var manyArrays = record._loadingRecordArrays;
5065
-
5066
- if (manyArrays) {
5067
- for (var i=0, l=manyArrays.length; i<l; i++) {
5068
- manyArrays[i].loadedRecord();
5069
- }
5195
+ //Need to update live arrays on loading
5196
+ recordWasLoaded: function(record) {
5197
+ var type = record.constructor;
5198
+ var recordArrays = this.filteredRecordArrays.get(type);
5199
+ var filter;
5070
5200
 
5071
- record._loadingRecordArrays = [];
5072
- }
5201
+ ember$data$lib$system$record_array_manager$$forEach(recordArrays, function(array) {
5202
+ filter = ember$data$lib$system$record_array_manager$$get(array, 'filterFunction');
5203
+ this.updateRecordArray(array, filter, type, record);
5204
+ }, this);
5073
5205
  },
5074
-
5075
5206
  /**
5076
5207
  Update an individual filter.
5077
5208
 
@@ -5094,7 +5225,7 @@
5094
5225
 
5095
5226
  if (shouldBeInArray) {
5096
5227
  if (!recordArrays.has(array)) {
5097
- array.pushRecord(record);
5228
+ array._pushRecord(record);
5098
5229
  recordArrays.add(array);
5099
5230
  }
5100
5231
  } else if (!shouldBeInArray) {
@@ -5117,9 +5248,10 @@
5117
5248
  */
5118
5249
  updateFilter: function(array, type, filter) {
5119
5250
  var typeMap = this.store.typeMapFor(type);
5120
- var records = typeMap.records, record;
5251
+ var records = typeMap.records;
5252
+ var record;
5121
5253
 
5122
- for (var i=0, l=records.length; i<l; i++) {
5254
+ for (var i = 0, l = records.length; i < l; i++) {
5123
5255
  record = records[i];
5124
5256
 
5125
5257
  if (!ember$data$lib$system$record_array_manager$$get(record, 'isDeleted') && !ember$data$lib$system$record_array_manager$$get(record, 'isEmpty')) {
@@ -5226,36 +5358,16 @@
5226
5358
  recordArrays.splice(index, 1);
5227
5359
  },
5228
5360
 
5229
- // Internally, we maintain a map of all unloaded IDs requested by
5230
- // a ManyArray. As the adapter loads data into the store, the
5231
- // store notifies any interested ManyArrays. When the ManyArray's
5232
- // total number of loading records drops to zero, it becomes
5233
- // `isLoaded` and fires a `didLoad` event.
5234
- registerWaitingRecordArray: function(record, array) {
5235
- var loadingRecordArrays = record._loadingRecordArrays || [];
5236
- loadingRecordArrays.push(array);
5237
- record._loadingRecordArrays = loadingRecordArrays;
5238
- },
5239
-
5240
- willDestroy: function(){
5241
- this._super();
5361
+ willDestroy: function() {
5362
+ this._super.apply(this, arguments);
5242
5363
 
5243
- ember$data$lib$system$record_array_manager$$forEach(ember$data$lib$system$record_array_manager$$flatten(ember$data$lib$system$record_array_manager$$values(this.filteredRecordArrays.values)), ember$data$lib$system$record_array_manager$$destroy);
5364
+ this.filteredRecordArrays.forEach(function(value) {
5365
+ ember$data$lib$system$record_array_manager$$forEach(ember$data$lib$system$record_array_manager$$flatten(value), ember$data$lib$system$record_array_manager$$destroy);
5366
+ });
5244
5367
  ember$data$lib$system$record_array_manager$$forEach(this._adapterPopulatedRecordArrays, ember$data$lib$system$record_array_manager$$destroy);
5245
5368
  }
5246
5369
  });
5247
5370
 
5248
- function ember$data$lib$system$record_array_manager$$values(obj) {
5249
- var result = [];
5250
- var keys = Ember.keys(obj);
5251
-
5252
- for (var i = 0; i < keys.length; i++) {
5253
- result.push(obj[keys[i]]);
5254
- }
5255
-
5256
- return result;
5257
- }
5258
-
5259
5371
  function ember$data$lib$system$record_array_manager$$destroy(entry) {
5260
5372
  entry.destroy();
5261
5373
  }
@@ -5547,6 +5659,7 @@
5547
5659
 
5548
5660
  rollback: function(record) {
5549
5661
  record.rollback();
5662
+ record.triggerLater('ready');
5550
5663
  }
5551
5664
  },
5552
5665
 
@@ -5614,6 +5727,7 @@
5614
5727
 
5615
5728
  rolledBack: function(record) {
5616
5729
  ember$data$lib$system$model$states$$get(record, 'errors').clear();
5730
+ record.triggerLater('ready');
5617
5731
  },
5618
5732
 
5619
5733
  becameValid: function(record) {
@@ -5635,7 +5749,8 @@
5635
5749
  // necessary.
5636
5750
 
5637
5751
  function ember$data$lib$system$model$states$$deepClone(object) {
5638
- var clone = {}, value;
5752
+ var clone = {};
5753
+ var value;
5639
5754
 
5640
5755
  for (var prop in object) {
5641
5756
  value = object[prop];
@@ -5686,6 +5801,11 @@
5686
5801
  record.transitionTo('deleted.saved');
5687
5802
  };
5688
5803
 
5804
+ ember$data$lib$system$model$states$$createdState.uncommitted.pushedData = function(record) {
5805
+ record.transitionTo('loaded.updated.uncommitted');
5806
+ record.triggerLater('didLoad');
5807
+ };
5808
+
5689
5809
  ember$data$lib$system$model$states$$createdState.uncommitted.propertyWasReset = Ember.K;
5690
5810
 
5691
5811
  function ember$data$lib$system$model$states$$assertAgainstUnloadRecord(record) {
@@ -5745,11 +5865,13 @@
5745
5865
 
5746
5866
  loadedData: function(record) {
5747
5867
  record.transitionTo('loaded.created.uncommitted');
5868
+ record.triggerLater('ready');
5748
5869
  },
5749
5870
 
5750
5871
  pushedData: function(record) {
5751
5872
  record.transitionTo('loaded.saved');
5752
5873
  record.triggerLater('didLoad');
5874
+ record.triggerLater('ready');
5753
5875
  }
5754
5876
  },
5755
5877
 
@@ -5771,6 +5893,7 @@
5771
5893
  pushedData: function(record) {
5772
5894
  record.transitionTo('loaded.saved');
5773
5895
  record.triggerLater('didLoad');
5896
+ record.triggerLater('ready');
5774
5897
  ember$data$lib$system$model$states$$set(record, 'isError', false);
5775
5898
  },
5776
5899
 
@@ -5890,6 +6013,7 @@
5890
6013
 
5891
6014
  rollback: function(record) {
5892
6015
  record.rollback();
6016
+ record.triggerLater('ready');
5893
6017
  },
5894
6018
 
5895
6019
  becomeDirty: Ember.K,
@@ -5897,6 +6021,7 @@
5897
6021
 
5898
6022
  rolledBack: function(record) {
5899
6023
  record.transitionTo('loaded.saved');
6024
+ record.triggerLater('ready');
5900
6025
  }
5901
6026
  },
5902
6027
 
@@ -5935,7 +6060,7 @@
5935
6060
 
5936
6061
  setup: function(record) {
5937
6062
  var store = ember$data$lib$system$model$states$$get(record, 'store');
5938
- store.dematerializeRecord(record);
6063
+ store._dematerializeRecord(record);
5939
6064
  },
5940
6065
 
5941
6066
  invokeLifecycleCallbacks: function(record) {
@@ -6052,7 +6177,7 @@
6052
6177
  record. This is useful for displaying all errors to the user.
6053
6178
 
6054
6179
  ```handlebars
6055
- {{#each message in errors.messages}}
6180
+ {{#each message in model.errors.messages}}
6056
6181
  <div class="error">
6057
6182
  {{message}}
6058
6183
  </div>
@@ -6292,34 +6417,34 @@
6292
6417
  var members = this.members.list;
6293
6418
  var member;
6294
6419
 
6295
- while (members.length > 0){
6420
+ while (members.length > 0) {
6296
6421
  member = members[0];
6297
6422
  this.removeRecord(member);
6298
6423
  }
6299
6424
  },
6300
6425
 
6301
- disconnect: function(){
6426
+ disconnect: function() {
6302
6427
  this.members.forEach(function(member) {
6303
6428
  this.removeRecordFromInverse(member);
6304
6429
  }, this);
6305
6430
  },
6306
6431
 
6307
- reconnect: function(){
6432
+ reconnect: function() {
6308
6433
  this.members.forEach(function(member) {
6309
6434
  this.addRecordToInverse(member);
6310
6435
  }, this);
6311
6436
  },
6312
6437
 
6313
- removeRecords: function(records){
6438
+ removeRecords: function(records) {
6314
6439
  var self = this;
6315
- ember$data$lib$system$relationships$state$relationship$$forEach(records, function(record){
6440
+ ember$data$lib$system$relationships$state$relationship$$forEach(records, function(record) {
6316
6441
  self.removeRecord(record);
6317
6442
  });
6318
6443
  },
6319
6444
 
6320
- addRecords: function(records, idx){
6445
+ addRecords: function(records, idx) {
6321
6446
  var self = this;
6322
- ember$data$lib$system$relationships$state$relationship$$forEach(records, function(record){
6447
+ ember$data$lib$system$relationships$state$relationship$$forEach(records, function(record) {
6323
6448
  self.addRecord(record, idx);
6324
6449
  if (idx !== undefined) {
6325
6450
  idx++;
@@ -6344,7 +6469,7 @@
6344
6469
  record._relationships[this.inverseKey].addCanonicalRecord(this.record);
6345
6470
  } else {
6346
6471
  if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
6347
- record._implicitRelationships[this.inverseKeyForImplicit] = new ember$data$lib$system$relationships$state$relationship$$Relationship(this.store, record, this.key, {options:{}});
6472
+ record._implicitRelationships[this.inverseKeyForImplicit] = new ember$data$lib$system$relationships$state$relationship$$Relationship(this.store, record, this.key, { options: {} });
6348
6473
  }
6349
6474
  record._implicitRelationships[this.inverseKeyForImplicit].addCanonicalRecord(this.record);
6350
6475
  }
@@ -6384,11 +6509,11 @@
6384
6509
  record._relationships[this.inverseKey].addRecord(this.record);
6385
6510
  } else {
6386
6511
  if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
6387
- record._implicitRelationships[this.inverseKeyForImplicit] = new ember$data$lib$system$relationships$state$relationship$$Relationship(this.store, record, this.key, {options:{}});
6512
+ record._implicitRelationships[this.inverseKeyForImplicit] = new ember$data$lib$system$relationships$state$relationship$$Relationship(this.store, record, this.key, { options: {} });
6388
6513
  }
6389
6514
  record._implicitRelationships[this.inverseKeyForImplicit].addRecord(this.record);
6390
6515
  }
6391
- this.record.updateRecordArrays();
6516
+ this.record.updateRecordArraysLater();
6392
6517
  }
6393
6518
  },
6394
6519
 
@@ -6467,7 +6592,7 @@
6467
6592
  },
6468
6593
 
6469
6594
  updateLink: function(link) {
6470
- Ember.warn("You have pushed a record of type '" + this.record.constructor.typeKey + "' with '" + this.key + "' as a link, but the association is not an aysnc relationship.", this.isAsync);
6595
+ Ember.warn("You have pushed a record of type '" + this.record.constructor.typeKey + "' with '" + this.key + "' as a link, but the association is not an async relationship.", this.isAsync);
6471
6596
  Ember.assert("You have pushed a record of type '" + this.record.constructor.typeKey + "' with '" + this.key + "' as a link, but the value of that link is not a string.", typeof link === 'string' || link === null);
6472
6597
  if (link !== this.link) {
6473
6598
  this.link = link;
@@ -6508,7 +6633,13 @@
6508
6633
  this._super$constructor(store, record, inverseKey, relationshipMeta);
6509
6634
  this.belongsToType = relationshipMeta.type;
6510
6635
  this.canonicalState = [];
6511
- this.manyArray = ember$data$lib$system$record_arrays$many_array$$default.create({ canonicalState:this.canonicalState, store:this.store, relationship:this, type:this.belongsToType, record:record});
6636
+ this.manyArray = ember$data$lib$system$record_arrays$many_array$$default.create({
6637
+ canonicalState: this.canonicalState,
6638
+ store: this.store,
6639
+ relationship: this,
6640
+ type: this.belongsToType,
6641
+ record: record
6642
+ });
6512
6643
  this.isPolymorphic = relationshipMeta.options.polymorphic;
6513
6644
  this.manyArray.isPolymorphic = this.isPolymorphic;
6514
6645
  };
@@ -6616,27 +6747,21 @@
6616
6747
  records = ember$data$lib$system$relationships$state$has_many$$setForArray(records);
6617
6748
 
6618
6749
  members.forEach(function(member) {
6619
- if (records.has(member)) return;
6750
+ if (records.has(member)) { return; }
6620
6751
 
6621
6752
  recordsToRemove.push(member);
6622
6753
  });
6623
6754
 
6624
6755
  this.removeCanonicalRecords(recordsToRemove);
6625
6756
 
6626
- var hasManyArray = this.manyArray;
6627
-
6628
6757
  // Using records.toArray() since currently using
6629
6758
  // removeRecord can modify length, messing stuff up
6630
6759
  // forEach since it directly looks at "length" each
6631
6760
  // iteration
6632
6761
  records = records.toArray();
6633
6762
  length = records.length;
6634
- for (i = 0; i < length; i++){
6763
+ for (i = 0; i < length; i++) {
6635
6764
  record = records[i];
6636
- //Need to preserve the order of incoming records
6637
- if (hasManyArray.objectAt(i) === record ) {
6638
- continue;
6639
- }
6640
6765
  this.removeCanonicalRecord(record);
6641
6766
  this.addCanonicalRecord(record, i);
6642
6767
  }
@@ -6644,7 +6769,7 @@
6644
6769
 
6645
6770
  ember$data$lib$system$relationships$state$has_many$$ManyRelationship.prototype.fetchLink = function() {
6646
6771
  var self = this;
6647
- return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records){
6772
+ return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records) {
6648
6773
  self.updateRecordsFromAdapter(records);
6649
6774
  return self.manyArray;
6650
6775
  });
@@ -6652,7 +6777,7 @@
6652
6777
 
6653
6778
  ember$data$lib$system$relationships$state$has_many$$ManyRelationship.prototype.findRecords = function() {
6654
6779
  var manyArray = this.manyArray;
6655
- return this.store.findMany(manyArray.toArray()).then(function(){
6780
+ return this.store.findMany(manyArray.toArray()).then(function() {
6656
6781
  //Goes away after the manyArray refactor
6657
6782
  manyArray.set('isLoaded', true);
6658
6783
  return manyArray;
@@ -6679,14 +6804,14 @@
6679
6804
  promise: promise
6680
6805
  });
6681
6806
  } else {
6682
- 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));
6807
+ 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));
6683
6808
 
6684
6809
  //TODO(Igor) WTF DO I DO HERE?
6685
6810
  if (!this.manyArray.get('isDestroyed')) {
6686
6811
  this.manyArray.set('isLoaded', true);
6687
6812
  }
6688
6813
  return this.manyArray;
6689
- }
6814
+ }
6690
6815
  };
6691
6816
 
6692
6817
  function ember$data$lib$system$relationships$state$has_many$$setForArray(array) {
@@ -6733,9 +6858,7 @@
6733
6858
 
6734
6859
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype._super$addCanonicalRecord = ember$data$lib$system$relationships$state$relationship$$default.prototype.addCanonicalRecord;
6735
6860
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype.addCanonicalRecord = function(newRecord) {
6736
- if (this.canonicalMembers.has(newRecord)){ return;}
6737
- var type = this.relationshipMeta.type;
6738
- Ember.assert("You can only add a '" + type.typeKey + "' record to this relationship", newRecord instanceof type);
6861
+ if (this.canonicalMembers.has(newRecord)) { return;}
6739
6862
 
6740
6863
  if (this.canonicalState) {
6741
6864
  this.removeCanonicalRecord(this.canonicalState);
@@ -6759,7 +6882,7 @@
6759
6882
 
6760
6883
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype._super$addRecord = ember$data$lib$system$relationships$state$relationship$$default.prototype.addRecord;
6761
6884
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype.addRecord = function(newRecord) {
6762
- if (this.members.has(newRecord)){ return;}
6885
+ if (this.members.has(newRecord)) { return;}
6763
6886
  var type = this.relationshipMeta.type;
6764
6887
  Ember.assert("You can only add a '" + type.typeKey + "' record to this relationship", (function () {
6765
6888
  if (newRecord instanceof type) {
@@ -6788,7 +6911,7 @@
6788
6911
 
6789
6912
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype._super$removeRecordFromOwn = ember$data$lib$system$relationships$state$relationship$$default.prototype.removeRecordFromOwn;
6790
6913
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype.removeRecordFromOwn = function(record) {
6791
- if (!this.members.has(record)){ return;}
6914
+ if (!this.members.has(record)) { return;}
6792
6915
  this.inverseRecord = null;
6793
6916
  this._super$removeRecordFromOwn(record);
6794
6917
  this.record.notifyBelongsToChanged(this.key);
@@ -6796,7 +6919,7 @@
6796
6919
 
6797
6920
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype._super$removeCanonicalRecordFromOwn = ember$data$lib$system$relationships$state$relationship$$default.prototype.removeCanonicalRecordFromOwn;
6798
6921
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype.removeCanonicalRecordFromOwn = function(record) {
6799
- if (!this.canonicalMembers.has(record)){ return;}
6922
+ if (!this.canonicalMembers.has(record)) { return;}
6800
6923
  this.canonicalState = null;
6801
6924
  this._super$removeCanonicalRecordFromOwn(record);
6802
6925
  };
@@ -6811,7 +6934,7 @@
6811
6934
 
6812
6935
  ember$data$lib$system$relationships$state$belongs_to$$BelongsToRelationship.prototype.fetchLink = function() {
6813
6936
  var self = this;
6814
- return this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record){
6937
+ return this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record) {
6815
6938
  if (record) {
6816
6939
  self.addRecord(record);
6817
6940
  }
@@ -6823,7 +6946,7 @@
6823
6946
  //TODO(Igor) flushCanonical here once our syncing is not stupid
6824
6947
  if (this.isAsync) {
6825
6948
  var promise;
6826
- if (this.link){
6949
+ if (this.link) {
6827
6950
  var self = this;
6828
6951
  promise = this.findLink().then(function() {
6829
6952
  return self.findRecord();
@@ -6849,41 +6972,401 @@
6849
6972
  var inverse = record.constructor.inverseFor(relationshipMeta.key);
6850
6973
 
6851
6974
  if (inverse) {
6852
- inverseKey = inverse.name;
6853
- }
6854
-
6855
- if (relationshipMeta.kind === 'hasMany'){
6856
- return new ember$data$lib$system$relationships$state$has_many$$default(store, record, inverseKey, relationshipMeta);
6975
+ inverseKey = inverse.name;
6857
6976
  }
6858
- else {
6859
- return new ember$data$lib$system$relationships$state$belongs_to$$default(store, record, inverseKey, relationshipMeta);
6977
+
6978
+ if (relationshipMeta.kind === 'hasMany') {
6979
+ return new ember$data$lib$system$relationships$state$has_many$$default(store, record, inverseKey, relationshipMeta);
6980
+ } else {
6981
+ return new ember$data$lib$system$relationships$state$belongs_to$$default(store, record, inverseKey, relationshipMeta);
6860
6982
  }
6861
6983
  };
6862
6984
 
6863
6985
  var ember$data$lib$system$relationships$state$create$$default = ember$data$lib$system$relationships$state$create$$createRelationshipFor;
6864
-
6865
6986
  /**
6866
6987
  @module ember-data
6867
6988
  */
6868
6989
 
6869
- var ember$data$lib$system$model$model$$get = Ember.get;
6870
- var ember$data$lib$system$model$model$$set = Ember.set;
6871
- var ember$data$lib$system$model$model$$Promise = Ember.RSVP.Promise;
6872
- var ember$data$lib$system$model$model$$forEach = Ember.ArrayPolyfills.forEach;
6873
- var ember$data$lib$system$model$model$$map = Ember.ArrayPolyfills.map;
6874
-
6875
- var ember$data$lib$system$model$model$$retrieveFromCurrentState = Ember.computed('currentState', function(key, value) {
6876
- return ember$data$lib$system$model$model$$get(ember$data$lib$system$model$model$$get(this, 'currentState'), key);
6877
- }).readOnly();
6990
+ var ember$data$lib$system$snapshot$$get = Ember.get;
6878
6991
 
6879
- var ember$data$lib$system$model$model$$_extractPivotNameCache = Ember.create(null);
6880
- var ember$data$lib$system$model$model$$_splitOnDotCache = Ember.create(null);
6992
+ /**
6993
+ @class Snapshot
6994
+ @namespace DS
6995
+ @private
6996
+ @constructor
6997
+ @param {DS.Model} record The record to create a snapshot from
6998
+ */
6999
+ function ember$data$lib$system$snapshot$$Snapshot(record) {
7000
+ this._attributes = Ember.create(null);
7001
+ this._belongsToRelationships = Ember.create(null);
7002
+ this._belongsToIds = Ember.create(null);
7003
+ this._hasManyRelationships = Ember.create(null);
7004
+ this._hasManyIds = Ember.create(null);
7005
+
7006
+ record.eachAttribute(function(keyName) {
7007
+ this._attributes[keyName] = ember$data$lib$system$snapshot$$get(record, keyName);
7008
+ }, this);
7009
+
7010
+ this.id = ember$data$lib$system$snapshot$$get(record, 'id');
7011
+ this.record = record;
7012
+ this.type = record.constructor;
7013
+ this.typeKey = record.constructor.typeKey;
6881
7014
 
6882
- function ember$data$lib$system$model$model$$splitOnDot(name) {
6883
- return ember$data$lib$system$model$model$$_splitOnDotCache[name] || (
6884
- (ember$data$lib$system$model$model$$_splitOnDotCache[name] = name.split('.'))
6885
- );
6886
- }
7015
+ // The following code is here to keep backwards compatibility when accessing
7016
+ // `constructor` directly.
7017
+ //
7018
+ // With snapshots you should use `type` instead of `constructor`.
7019
+ //
7020
+ // Remove for Ember Data 1.0.
7021
+ if (Ember.platform.hasPropertyAccessors) {
7022
+ var callDeprecate = true;
7023
+
7024
+ Ember.defineProperty(this, 'constructor', {
7025
+ get: function() {
7026
+ // Ugly hack since accessing error.stack (done in `Ember.deprecate()`)
7027
+ // causes the internals of Chrome to access the constructor, which then
7028
+ // causes an infinite loop if accessed and calls `Ember.deprecate()`
7029
+ // again.
7030
+ if (callDeprecate) {
7031
+ callDeprecate = false;
7032
+ Ember.deprecate('Usage of `snapshot.constructor` is deprecated, use `snapshot.type` instead.');
7033
+ callDeprecate = true;
7034
+ }
7035
+
7036
+ return this.type;
7037
+ }
7038
+ });
7039
+ } else {
7040
+ this.constructor = this.type;
7041
+ }
7042
+ }
7043
+
7044
+ ember$data$lib$system$snapshot$$Snapshot.prototype = {
7045
+ constructor: ember$data$lib$system$snapshot$$Snapshot,
7046
+
7047
+ /**
7048
+ The id of the snapshot's underlying record
7049
+
7050
+ Example
7051
+
7052
+ ```javascript
7053
+ var post = store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
7054
+ var snapshot = post._createSnapshot();
7055
+
7056
+ snapshot.id; // => '1'
7057
+ ```
7058
+
7059
+ @property id
7060
+ @type {String}
7061
+ */
7062
+ id: null,
7063
+
7064
+ /**
7065
+ The underlying record for this snapshot. Can be used to access methods and
7066
+ properties defined on the record.
7067
+
7068
+ Example
7069
+
7070
+ ```javascript
7071
+ var json = snapshot.record.toJSON();
7072
+ ```
7073
+
7074
+ @property record
7075
+ @type {DS.Model}
7076
+ */
7077
+ record: null,
7078
+
7079
+ /**
7080
+ The type of the underlying record for this snapshot, as a subclass of DS.Model.
7081
+
7082
+ @property type
7083
+ @type {subclass of DS.Model}
7084
+ */
7085
+ type: null,
7086
+
7087
+ /**
7088
+ The name of the type of the underlying record for this snapshot, as a string.
7089
+
7090
+ @property typeKey
7091
+ @type {String}
7092
+ */
7093
+ typeKey: null,
7094
+
7095
+ /**
7096
+ Returns the value of an attribute.
7097
+
7098
+ Example
7099
+
7100
+ ```javascript
7101
+ var post = store.createRecord('post', { author: 'Tomster', title: 'Ember.js rocks' });
7102
+ var snapshot = post._createSnapshot();
7103
+
7104
+ snapshot.attr('author'); // => 'Tomster'
7105
+ snapshot.attr('title'); // => 'Ember.js rocks'
7106
+ ```
7107
+
7108
+ Note: Values are loaded eagerly and cached when the snapshot is created.
7109
+
7110
+ @method attr
7111
+ @param {String} keyName
7112
+ @return {Object} The attribute value or undefined
7113
+ */
7114
+ attr: function(keyName) {
7115
+ if (keyName in this._attributes) {
7116
+ return this._attributes[keyName];
7117
+ }
7118
+ throw new Ember.Error("Model '" + Ember.inspect(this.record) + "' has no attribute named '" + keyName + "' defined.");
7119
+ },
7120
+
7121
+ /**
7122
+ Returns all attributes and their corresponding values.
7123
+
7124
+ Example
7125
+
7126
+ ```javascript
7127
+ var post = store.createRecord('post', { author: 'Tomster', title: 'Ember.js rocks' });
7128
+ var snapshot = post._createSnapshot();
7129
+
7130
+ snapshot.attributes(); // => { author: 'Tomster', title: 'Ember.js rocks' }
7131
+ ```
7132
+
7133
+ @method attributes
7134
+ @return {Array} All attributes for the current snapshot
7135
+ */
7136
+ attributes: function() {
7137
+ return Ember.copy(this._attributes);
7138
+ },
7139
+
7140
+ /**
7141
+ Returns the current value of a belongsTo relationship.
7142
+
7143
+ `belongsTo` takes an optional hash of options as a second parameter,
7144
+ currently supported options are:
7145
+
7146
+ - `id`: set to `true` if you only want the ID of the related record to be
7147
+ returned.
7148
+
7149
+ Example
7150
+
7151
+ ```javascript
7152
+ var post = store.push('post', { id: 1, title: 'Hello World' });
7153
+ var comment = store.createRecord('comment', { body: 'Lorem ipsum', post: post });
7154
+ var snapshot = comment._createSnapshot();
7155
+
7156
+ snapshot.belongsTo('post'); // => DS.Snapshot of post
7157
+ snapshot.belongsTo('post', { id: true }); // => '1'
7158
+ ```
7159
+
7160
+ Calling `belongsTo` will return a new Snapshot as long as there's any
7161
+ data available, such as an ID. If there's no data available `belongsTo` will
7162
+ return undefined.
7163
+
7164
+ Note: Relationships are loaded lazily and cached upon first access.
7165
+
7166
+ @method belongsTo
7167
+ @param {String} keyName
7168
+ @param {Object} [options]
7169
+ @return {DS.Snapshot|String|undefined} A snapshot or ID of a belongsTo relationship, or undefined
7170
+ */
7171
+ belongsTo: function(keyName, options) {
7172
+ var id = options && options.id;
7173
+ var result;
7174
+ var relationship, inverseRecord;
7175
+
7176
+ if (id && keyName in this._belongsToIds) {
7177
+ return this._belongsToIds[keyName];
7178
+ }
7179
+
7180
+ if (!id && keyName in this._belongsToRelationships) {
7181
+ return this._belongsToRelationships[keyName];
7182
+ }
7183
+
7184
+ relationship = this.record._relationships[keyName];
7185
+ if (!(relationship && relationship.relationshipMeta.kind === 'belongsTo')) {
7186
+ throw new Ember.Error("Model '" + Ember.inspect(this.record) + "' has no belongsTo relationship named '" + keyName + "' defined.");
7187
+ }
7188
+
7189
+ inverseRecord = ember$data$lib$system$snapshot$$get(relationship, 'inverseRecord');
7190
+ if (id) {
7191
+ if (inverseRecord) {
7192
+ result = ember$data$lib$system$snapshot$$get(inverseRecord, 'id');
7193
+ }
7194
+ this._belongsToIds[keyName] = result;
7195
+ } else {
7196
+ if (inverseRecord) {
7197
+ result = inverseRecord._createSnapshot();
7198
+ }
7199
+ this._belongsToRelationships[keyName] = result;
7200
+ }
7201
+
7202
+ return result;
7203
+ },
7204
+
7205
+ /**
7206
+ Returns the current value of a hasMany relationship.
7207
+
7208
+ `hasMany` takes an optional hash of options as a second parameter,
7209
+ currently supported options are:
7210
+
7211
+ - `ids`: set to `true` if you only want the IDs of the related records to be
7212
+ returned.
7213
+
7214
+ Example
7215
+
7216
+ ```javascript
7217
+ var post = store.createRecord('post', { title: 'Hello World', comments: [2, 3] });
7218
+ var snapshot = post._createSnapshot();
7219
+
7220
+ snapshot.hasMany('comments'); // => [DS.Snapshot, DS.Snapshot]
7221
+ snapshot.hasMany('comments', { ids: true }); // => ['2', '3']
7222
+ ```
7223
+
7224
+ Note: Relationships are loaded lazily and cached upon first access.
7225
+
7226
+ @method hasMany
7227
+ @param {String} keyName
7228
+ @param {Object} [options]
7229
+ @return {Array} An array of snapshots or IDs of a hasMany relationship
7230
+ */
7231
+ hasMany: function(keyName, options) {
7232
+ var ids = options && options.ids;
7233
+ var results = [];
7234
+ var relationship, members;
7235
+
7236
+ if (ids && keyName in this._hasManyIds) {
7237
+ return this._hasManyIds[keyName];
7238
+ }
7239
+
7240
+ if (!ids && keyName in this._hasManyRelationships) {
7241
+ return this._hasManyRelationships[keyName];
7242
+ }
7243
+
7244
+ relationship = this.record._relationships[keyName];
7245
+ if (!(relationship && relationship.relationshipMeta.kind === 'hasMany')) {
7246
+ throw new Ember.Error("Model '" + Ember.inspect(this.record) + "' has no hasMany relationship named '" + keyName + "' defined.");
7247
+ }
7248
+
7249
+ members = ember$data$lib$system$snapshot$$get(relationship, 'members');
7250
+
7251
+ if (ids) {
7252
+ members.forEach(function(member) {
7253
+ results.push(ember$data$lib$system$snapshot$$get(member, 'id'));
7254
+ });
7255
+ this._hasManyIds[keyName] = results;
7256
+ } else {
7257
+ members.forEach(function(member) {
7258
+ results.push(member._createSnapshot());
7259
+ });
7260
+ this._hasManyRelationships[keyName] = results;
7261
+ }
7262
+
7263
+ return results;
7264
+ },
7265
+
7266
+ /**
7267
+ Iterates through all the attributes of the model, calling the passed
7268
+ function on each attribute.
7269
+
7270
+ Example
7271
+
7272
+ ```javascript
7273
+ snapshot.eachAttribute(function(name, meta) {
7274
+ // ...
7275
+ });
7276
+ ```
7277
+
7278
+ @method eachAttribute
7279
+ @param {Function} callback the callback to execute
7280
+ @param {Object} [binding] the value to which the callback's `this` should be bound
7281
+ */
7282
+ eachAttribute: function(callback, binding) {
7283
+ this.record.eachAttribute(callback, binding);
7284
+ },
7285
+
7286
+ /**
7287
+ Iterates through all the relationships of the model, calling the passed
7288
+ function on each relationship.
7289
+
7290
+ Example
7291
+
7292
+ ```javascript
7293
+ snapshot.eachRelationship(function(name, relationship) {
7294
+ // ...
7295
+ });
7296
+ ```
7297
+
7298
+ @method eachRelationship
7299
+ @param {Function} callback the callback to execute
7300
+ @param {Object} [binding] the value to which the callback's `this` should be bound
7301
+ */
7302
+ eachRelationship: function(callback, binding) {
7303
+ this.record.eachRelationship(callback, binding);
7304
+ },
7305
+
7306
+ /**
7307
+ @method get
7308
+ @param {String} keyName
7309
+ @return {Object} The property value
7310
+ @deprecated Use [attr](#method_attr), [belongsTo](#method_belongsTo) or [hasMany](#method_hasMany) instead
7311
+ */
7312
+ get: function(keyName) {
7313
+ Ember.deprecate('Using DS.Snapshot.get() is deprecated. Use .attr(), .belongsTo() or .hasMany() instead.');
7314
+
7315
+ if (keyName === 'id') {
7316
+ return this.id;
7317
+ }
7318
+
7319
+ if (keyName in this._attributes) {
7320
+ return this.attr(keyName);
7321
+ }
7322
+
7323
+ var relationship = this.record._relationships[keyName];
7324
+
7325
+ if (relationship && relationship.relationshipMeta.kind === 'belongsTo') {
7326
+ return this.belongsTo(keyName);
7327
+ }
7328
+ if (relationship && relationship.relationshipMeta.kind === 'hasMany') {
7329
+ return this.hasMany(keyName);
7330
+ }
7331
+
7332
+ return ember$data$lib$system$snapshot$$get(this.record, keyName);
7333
+ },
7334
+
7335
+ /**
7336
+ @method unknownProperty
7337
+ @param {String} keyName
7338
+ @return {Object} The property value
7339
+ @deprecated Use [attr](#method_attr), [belongsTo](#method_belongsTo) or [hasMany](#method_hasMany) instead
7340
+ */
7341
+ unknownProperty: function(keyName) {
7342
+ return this.get(keyName);
7343
+ }
7344
+ };
7345
+
7346
+ var ember$data$lib$system$snapshot$$default = ember$data$lib$system$snapshot$$Snapshot;
7347
+
7348
+ /**
7349
+ @module ember-data
7350
+ */
7351
+
7352
+ var ember$data$lib$system$model$model$$get = Ember.get;
7353
+ var ember$data$lib$system$model$model$$set = Ember.set;
7354
+ var ember$data$lib$system$model$model$$Promise = Ember.RSVP.Promise;
7355
+ var ember$data$lib$system$model$model$$forEach = Ember.ArrayPolyfills.forEach;
7356
+ var ember$data$lib$system$model$model$$map = Ember.ArrayPolyfills.map;
7357
+
7358
+ var ember$data$lib$system$model$model$$retrieveFromCurrentState = Ember.computed('currentState', function(key, value) {
7359
+ return ember$data$lib$system$model$model$$get(ember$data$lib$system$model$model$$get(this, 'currentState'), key);
7360
+ }).readOnly();
7361
+
7362
+ var ember$data$lib$system$model$model$$_extractPivotNameCache = Ember.create(null);
7363
+ var ember$data$lib$system$model$model$$_splitOnDotCache = Ember.create(null);
7364
+
7365
+ function ember$data$lib$system$model$model$$splitOnDot(name) {
7366
+ return ember$data$lib$system$model$model$$_splitOnDotCache[name] || (
7367
+ (ember$data$lib$system$model$model$$_splitOnDotCache[name] = name.split('.'))
7368
+ );
7369
+ }
6887
7370
 
6888
7371
  function ember$data$lib$system$model$model$$extractPivotName(name) {
6889
7372
  return ember$data$lib$system$model$model$$_extractPivotNameCache[name] || (
@@ -6891,6 +7374,33 @@
6891
7374
  );
6892
7375
  }
6893
7376
 
7377
+ // Like Ember.merge, but instead returns a list of keys
7378
+ // for values that fail a strict equality check
7379
+ // instead of the original object.
7380
+ function ember$data$lib$system$model$model$$mergeAndReturnChangedKeys(original, updates) {
7381
+ var changedKeys = [];
7382
+
7383
+ if (!updates || typeof updates !== 'object') {
7384
+ return changedKeys;
7385
+ }
7386
+
7387
+ var keys = Ember.keys(updates);
7388
+ var length = keys.length;
7389
+ var i, val, key;
7390
+
7391
+ for (i = 0; i < length; i++) {
7392
+ key = keys[i];
7393
+ val = updates[key];
7394
+
7395
+ if (original[key] !== val) {
7396
+ changedKeys.push(key);
7397
+ }
7398
+
7399
+ original[key] = val;
7400
+ }
7401
+ return changedKeys;
7402
+ }
7403
+
6894
7404
  /**
6895
7405
 
6896
7406
  The model class that all Ember Data records descend from.
@@ -6903,7 +7413,6 @@
6903
7413
  var ember$data$lib$system$model$model$$Model = Ember.Object.extend(Ember.Evented, {
6904
7414
  _recordArrays: undefined,
6905
7415
  _relationships: undefined,
6906
- _loadingRecordArrays: undefined,
6907
7416
  /**
6908
7417
  If this property is `true` the record is in the `empty`
6909
7418
  state. Empty is the first state all records enter after they have
@@ -7232,9 +7741,20 @@
7232
7741
  toJSON: function(options) {
7233
7742
  // container is for lazy transform lookups
7234
7743
  var serializer = ember$data$lib$serializers$json_serializer$$default.create({ container: this.container });
7235
- return serializer.serialize(this, options);
7744
+ var snapshot = this._createSnapshot();
7745
+
7746
+ return serializer.serialize(snapshot, options);
7236
7747
  },
7237
7748
 
7749
+ /**
7750
+ Fired when the record is ready to be interacted with,
7751
+ that is either loaded from the server or created locally.
7752
+
7753
+ @event ready
7754
+ */
7755
+ ready: function() {
7756
+ this.store.recordArrayManager.recordWasLoaded(this);
7757
+ },
7238
7758
  /**
7239
7759
  Fired when the record is loaded from the server.
7240
7760
 
@@ -7290,7 +7810,7 @@
7290
7810
  _data: null,
7291
7811
 
7292
7812
  init: function() {
7293
- this._super();
7813
+ this._super.apply(this, arguments);
7294
7814
  this._setup();
7295
7815
  },
7296
7816
 
@@ -7325,7 +7845,7 @@
7325
7845
  var model = this;
7326
7846
  //TODO Move into a getter for better perf
7327
7847
  this.constructor.eachRelationship(function(key, descriptor) {
7328
- model._relationships[key] = ember$data$lib$system$relationships$state$create$$default(model, descriptor, model.store);
7848
+ model._relationships[key] = ember$data$lib$system$relationships$state$create$$default(model, descriptor, model.store);
7329
7849
  });
7330
7850
 
7331
7851
  },
@@ -7365,7 +7885,9 @@
7365
7885
  } while (!state.hasOwnProperty(pivotName));
7366
7886
 
7367
7887
  var path = ember$data$lib$system$model$model$$splitOnDot(name);
7368
- var setups = [], enters = [], i, l;
7888
+ var setups = [];
7889
+ var enters = [];
7890
+ var i, l;
7369
7891
 
7370
7892
  for (i=0, l=path.length; i<l; i++) {
7371
7893
  state = state[path[i]];
@@ -7511,7 +8033,7 @@
7511
8033
  clearRelationships: function() {
7512
8034
  this.eachRelationship(function(name, relationship) {
7513
8035
  var rel = this._relationships[name];
7514
- if (rel){
8036
+ if (rel) {
7515
8037
  //TODO(Igor) figure out whether we want to clear or disconnect
7516
8038
  rel.clear();
7517
8039
  rel.destroy();
@@ -7581,7 +8103,7 @@
7581
8103
  _preloadRelationship: function(key, preloadValue) {
7582
8104
  var relationshipMeta = this.constructor.metaForProperty(key);
7583
8105
  var type = relationshipMeta.type;
7584
- if (relationshipMeta.kind === 'hasMany'){
8106
+ if (relationshipMeta.kind === 'hasMany') {
7585
8107
  this._preloadHasMany(key, preloadValue, type);
7586
8108
  } else {
7587
8109
  this._preloadBelongsTo(key, preloadValue, type);
@@ -7600,7 +8122,7 @@
7600
8122
  this._relationships[key].updateRecordsFromAdapter(recordsToSet);
7601
8123
  },
7602
8124
 
7603
- _preloadBelongsTo: function(key, preloadValue, type){
8125
+ _preloadBelongsTo: function(key, preloadValue, type) {
7604
8126
  var recordToSet = this._convertStringOrNumberIntoRecord(preloadValue, type);
7605
8127
 
7606
8128
  //We use the pathway of setting the hasMany as if it came from the adapter
@@ -7609,7 +8131,7 @@
7609
8131
  },
7610
8132
 
7611
8133
  _convertStringOrNumberIntoRecord: function(value, type) {
7612
- if (Ember.typeOf(value) === 'string' || Ember.typeOf(value) === 'number'){
8134
+ if (Ember.typeOf(value) === 'string' || Ember.typeOf(value) === 'number') {
7613
8135
  return this.store.recordForId(type, value);
7614
8136
  }
7615
8137
  return value;
@@ -7622,7 +8144,7 @@
7622
8144
  _notifyProperties: function(keys) {
7623
8145
  Ember.beginPropertyChanges();
7624
8146
  var key;
7625
- for (var i = 0, length = keys.length; i < length; i++){
8147
+ for (var i = 0, length = keys.length; i < length; i++) {
7626
8148
  key = keys[i];
7627
8149
  this.notifyPropertyChange(key);
7628
8150
  }
@@ -7679,10 +8201,11 @@
7679
8201
  @method adapterDidCommit
7680
8202
  */
7681
8203
  adapterDidCommit: function(data) {
8204
+ var changedKeys;
7682
8205
  ember$data$lib$system$model$model$$set(this, 'isError', false);
7683
8206
 
7684
8207
  if (data) {
7685
- this._data = data;
8208
+ changedKeys = ember$data$lib$system$model$model$$mergeAndReturnChangedKeys(this._data, data);
7686
8209
  } else {
7687
8210
  ember$data$lib$system$merge$$default(this._data, this._inFlightAttributes);
7688
8211
  }
@@ -7694,7 +8217,7 @@
7694
8217
 
7695
8218
  if (!data) { return; }
7696
8219
 
7697
- this._notifyProperties(Ember.keys(data));
8220
+ this._notifyProperties(changedKeys);
7698
8221
  },
7699
8222
 
7700
8223
  /**
@@ -7727,11 +8250,11 @@
7727
8250
  setupData: function(data) {
7728
8251
  Ember.assert("Expected an object as `data` in `setupData`", Ember.typeOf(data) === 'object');
7729
8252
 
7730
- Ember.merge(this._data, data);
8253
+ var changedKeys = ember$data$lib$system$model$model$$mergeAndReturnChangedKeys(this._data, data);
7731
8254
 
7732
8255
  this.pushedData();
7733
8256
 
7734
- this._notifyProperties(Ember.keys(data));
8257
+ this._notifyProperties(changedKeys);
7735
8258
  },
7736
8259
 
7737
8260
  materializeId: function(id) {
@@ -7739,7 +8262,7 @@
7739
8262
  },
7740
8263
 
7741
8264
  materializeAttributes: function(attributes) {
7742
- Ember.assert("Must pass a hash of attributes to materializeAttributes", !!attributes);
8265
+ Ember.assert("Must pass an object to materializeAttributes", !!attributes);
7743
8266
  ember$data$lib$system$merge$$default(this._data, attributes);
7744
8267
  },
7745
8268
 
@@ -7793,6 +8316,14 @@
7793
8316
  this._notifyProperties(dirtyKeys);
7794
8317
  },
7795
8318
 
8319
+ /**
8320
+ @method _createSnapshot
8321
+ @private
8322
+ */
8323
+ _createSnapshot: function() {
8324
+ return new ember$data$lib$system$snapshot$$default(this);
8325
+ },
8326
+
7796
8327
  toStringExtension: function() {
7797
8328
  return ember$data$lib$system$model$model$$get(this, 'id');
7798
8329
  },
@@ -7805,7 +8336,7 @@
7805
8336
 
7806
8337
  ```javascript
7807
8338
  record.set('name', 'Tomster');
7808
- record.save().then(function(){
8339
+ record.save().then(function() {
7809
8340
  // Success callback
7810
8341
  }, function() {
7811
8342
  // Error callback
@@ -7859,8 +8390,8 @@
7859
8390
 
7860
8391
  var record = this;
7861
8392
  var promiseLabel = "DS: Model#reload of " + this;
7862
- var promise = new ember$data$lib$system$model$model$$Promise(function(resolve){
7863
- record.send('reloadRecord', resolve);
8393
+ var promise = new ember$data$lib$system$model$model$$Promise(function(resolve) {
8394
+ record.send('reloadRecord', resolve);
7864
8395
  }, promiseLabel).then(function() {
7865
8396
  record.set('isReloading', false);
7866
8397
  record.set('isError', false);
@@ -7885,14 +8416,12 @@
7885
8416
  */
7886
8417
  adapterDidInvalidate: function(errors) {
7887
8418
  var recordErrors = ember$data$lib$system$model$model$$get(this, 'errors');
7888
- function addError(name) {
7889
- if (errors[name]) {
7890
- recordErrors.add(name, errors[name]);
8419
+ for (var key in errors) {
8420
+ if (!errors.hasOwnProperty(key)) {
8421
+ continue;
7891
8422
  }
8423
+ recordErrors.add(key, errors[key]);
7892
8424
  }
7893
-
7894
- this.eachAttribute(addError);
7895
- this.eachRelationship(addError);
7896
8425
  this._saveWasRejected();
7897
8426
  },
7898
8427
 
@@ -7929,7 +8458,7 @@
7929
8458
  var args = new Array(length - 1);
7930
8459
  var name = arguments[0];
7931
8460
 
7932
- for (var i = 1; i < length; i++ ){
8461
+ for (var i = 1; i < length; i++) {
7933
8462
  args[i - 1] = arguments[i];
7934
8463
  }
7935
8464
 
@@ -7941,7 +8470,7 @@
7941
8470
  var length = arguments.length;
7942
8471
  var args = new Array(length);
7943
8472
 
7944
- for (var i = 0; i < length; i++ ){
8473
+ for (var i = 0; i < length; i++) {
7945
8474
  args[i] = arguments[i];
7946
8475
  }
7947
8476
 
@@ -7960,7 +8489,7 @@
7960
8489
  },
7961
8490
 
7962
8491
  willDestroy: function() {
7963
- this._super();
8492
+ this._super.apply(this, arguments);
7964
8493
  this.clearRelationships();
7965
8494
  },
7966
8495
 
@@ -8365,7 +8894,7 @@
8365
8894
  Define your application's store like this:
8366
8895
 
8367
8896
  ```javascript
8368
- MyApp.Store = DS.Store.extend();
8897
+ MyApp.ApplicationStore = DS.Store.extend();
8369
8898
  ```
8370
8899
 
8371
8900
  Most Ember.js applications will only have a single `DS.Store` that is
@@ -8473,7 +9002,8 @@
8473
9002
  @param {Object} options an options hash
8474
9003
  */
8475
9004
  serialize: function(record, options) {
8476
- return this.serializerFor(record.constructor.typeKey).serialize(record, options);
9005
+ var snapshot = record._createSnapshot();
9006
+ return this.serializerFor(snapshot.typeKey).serialize(snapshot, options);
8477
9007
  },
8478
9008
 
8479
9009
  /**
@@ -8541,7 +9071,7 @@
8541
9071
  // to avoid conflicts.
8542
9072
 
8543
9073
  if (ember$data$lib$system$store$$isNone(properties.id)) {
8544
- properties.id = this._generateId(type);
9074
+ properties.id = this._generateId(type, properties);
8545
9075
  }
8546
9076
 
8547
9077
  // Coerce ID to a string
@@ -8566,13 +9096,14 @@
8566
9096
  @method _generateId
8567
9097
  @private
8568
9098
  @param {String} type
9099
+ @param {Object} properties from the new record
8569
9100
  @return {String} if the adapter can generate one, an ID
8570
9101
  */
8571
- _generateId: function(type) {
9102
+ _generateId: function(type, properties) {
8572
9103
  var adapter = this.adapterFor(type);
8573
9104
 
8574
9105
  if (adapter && adapter.generateIdForRecord) {
8575
- return adapter.generateIdForRecord(this);
9106
+ return adapter.generateIdForRecord(this, type, properties);
8576
9107
  }
8577
9108
 
8578
9109
  return null;
@@ -8680,7 +9211,8 @@
8680
9211
 
8681
9212
  This will ask the adapter's `findAll` method to find the records for the
8682
9213
  given type, and return a promise that will be resolved once the server
8683
- returns the values.
9214
+ returns the values. The promise will resolve into all records of this type
9215
+ present in the store, even if the server only returns a subset of them.
8684
9216
 
8685
9217
  ---
8686
9218
 
@@ -8691,9 +9223,37 @@
8691
9223
  store.find('person', { page: 1 });
8692
9224
  ```
8693
9225
 
8694
- This will ask the adapter's `findQuery` method to find the records for
8695
- the query, and return a promise that will be resolved once the server
8696
- responds.
9226
+ By passing an object `{page: 1}` as an argument to the find method, it
9227
+ delegates to the adapter's findQuery method. The adapter then makes
9228
+ a call to the server, transforming the object `{page: 1}` as parameters
9229
+ that are sent along, and will return a RecordArray when the promise
9230
+ resolves.
9231
+
9232
+ Exposing queries this way seems preferable to creating an abstract query
9233
+ language for all server-side queries, and then require all adapters to
9234
+ implement them.
9235
+
9236
+ The call made to the server, using a Rails backend, will look something like this:
9237
+
9238
+ ```
9239
+ Started GET "/api/v1/person?page=1"
9240
+ Processing by Api::V1::PersonsController#index as HTML
9241
+ Parameters: {"page"=>"1"}
9242
+ ```
9243
+
9244
+ If you do something like this:
9245
+
9246
+ ```javascript
9247
+ store.find('person', {ids: [1, 2, 3]});
9248
+ ```
9249
+
9250
+ The call to the server, using a Rails backend, will look something like this:
9251
+
9252
+ ```
9253
+ Started GET "/api/v1/person?ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=3"
9254
+ Processing by Api::V1::PersonsController#index as HTML
9255
+ Parameters: {"ids"=>["1", "2", "3"]}
9256
+ ```
8697
9257
 
8698
9258
  @method find
8699
9259
  @param {String or subclass of DS.Model} type
@@ -8737,13 +9297,13 @@
8737
9297
  });
8738
9298
  ```
8739
9299
 
8740
- @method fetch
9300
+ @method fetchById
8741
9301
  @param {String or subclass of DS.Model} type
8742
9302
  @param {String|Integer} id
8743
9303
  @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
8744
9304
  @return {Promise} promise
8745
9305
  */
8746
- fetch: function(type, id, preload) {
9306
+ fetchById: function(type, id, preload) {
8747
9307
  if (this.hasRecordForId(type, id)) {
8748
9308
  return this.getById(type, id).reload();
8749
9309
  } else {
@@ -8751,6 +9311,33 @@
8751
9311
  }
8752
9312
  },
8753
9313
 
9314
+ /**
9315
+ This method returns a fresh collection from the server, regardless of if there is already records
9316
+ in the store or not.
9317
+
9318
+ @method fetchAll
9319
+ @param {String or subclass of DS.Model} type
9320
+ @return {Promise} promise
9321
+ */
9322
+ fetchAll: function(type) {
9323
+ type = this.modelFor(type);
9324
+
9325
+ return this._fetchAll(type, this.all(type));
9326
+ },
9327
+
9328
+ /**
9329
+ @method fetch
9330
+ @param {String or subclass of DS.Model} type
9331
+ @param {String|Integer} id
9332
+ @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
9333
+ @return {Promise} promise
9334
+ @deprecated Use [fetchById](#method_fetchById) instead
9335
+ */
9336
+ fetch: function(type, id, preload) {
9337
+ Ember.deprecate('Using store.fetch() has been deprecated. Use store.fetchById for fetching individual records or store.fetchAll for collections');
9338
+ return this.fetchById(type, id, preload);
9339
+ },
9340
+
8754
9341
  /**
8755
9342
  This method returns a record for a given type and id combination.
8756
9343
 
@@ -8779,7 +9366,7 @@
8779
9366
  if (ember$data$lib$system$store$$get(record, 'isEmpty')) {
8780
9367
  fetchedRecord = this.scheduleFetch(record);
8781
9368
  //TODO double check about reloading
8782
- } else if (ember$data$lib$system$store$$get(record, 'isLoading')){
9369
+ } else if (ember$data$lib$system$store$$get(record, 'isLoading')) {
8783
9370
  fetchedRecord = record._loadingPromise;
8784
9371
  }
8785
9372
 
@@ -8844,7 +9431,7 @@
8844
9431
 
8845
9432
  record.loadingData(promise);
8846
9433
 
8847
- if (!this._pendingFetch.get(type)){
9434
+ if (!this._pendingFetch.get(type)) {
8848
9435
  this._pendingFetch.set(type, [recordResolverPair]);
8849
9436
  } else {
8850
9437
  this._pendingFetch.get(type).push(recordResolverPair);
@@ -8854,7 +9441,7 @@
8854
9441
  return promise;
8855
9442
  },
8856
9443
 
8857
- flushAllPendingFetches: function(){
9444
+ flushAllPendingFetches: function() {
8858
9445
  if (this.isDestroyed || this.isDestroying) {
8859
9446
  return;
8860
9447
  }
@@ -8874,9 +9461,9 @@
8874
9461
  }
8875
9462
 
8876
9463
  function resolveFoundRecords(records) {
8877
- ember$data$lib$system$store$$forEach(records, function(record){
9464
+ ember$data$lib$system$store$$forEach(records, function(record) {
8878
9465
  var pair = Ember.A(recordResolverPairs).findBy('record', record);
8879
- if (pair){
9466
+ if (pair) {
8880
9467
  var resolver = pair.resolver;
8881
9468
  resolver.resolve(record);
8882
9469
  }
@@ -8897,9 +9484,9 @@
8897
9484
  }
8898
9485
 
8899
9486
  function rejectRecords(records, error) {
8900
- ember$data$lib$system$store$$forEach(records, function(record){
9487
+ ember$data$lib$system$store$$forEach(records, function(record) {
8901
9488
  var pair = Ember.A(recordResolverPairs).findBy('record', record);
8902
- if (pair){
9489
+ if (pair) {
8903
9490
  var resolver = pair.resolver;
8904
9491
  resolver.reject(error);
8905
9492
  }
@@ -9121,19 +9708,17 @@
9121
9708
  @return {DS.AdapterPopulatedRecordArray}
9122
9709
  */
9123
9710
  findAll: function(typeName) {
9124
- var type = this.modelFor(typeName);
9125
-
9126
- return this.fetchAll(type, this.all(type));
9711
+ return this.fetchAll(typeName);
9127
9712
  },
9128
9713
 
9129
9714
  /**
9130
- @method fetchAll
9715
+ @method _fetchAll
9131
9716
  @private
9132
9717
  @param {DS.Model} type
9133
9718
  @param {DS.RecordArray} array
9134
9719
  @return {Promise} promise
9135
9720
  */
9136
- fetchAll: function(type, array) {
9721
+ _fetchAll: function(type, array) {
9137
9722
  var adapter = this.adapterFor(type);
9138
9723
  var sinceToken = this.typeMapFor(type).metadata.since;
9139
9724
 
@@ -9353,9 +9938,8 @@
9353
9938
  // ............
9354
9939
 
9355
9940
  /**
9356
- If the adapter updates attributes or acknowledges creation
9357
- or deletion, the record will notify the store to update its
9358
- membership in any filters.
9941
+ If the adapter updates attributes the record will notify
9942
+ the store to update its membership in any filters.
9359
9943
  To avoid thrashing, this method is invoked only once per
9360
9944
 
9361
9945
  run loop per record.
@@ -9402,7 +9986,8 @@
9402
9986
  this._pendingSave = [];
9403
9987
 
9404
9988
  ember$data$lib$system$store$$forEach(pending, function(tuple) {
9405
- var record = tuple[0], resolver = tuple[1];
9989
+ var record = tuple[0];
9990
+ var resolver = tuple[1];
9406
9991
  var adapter = this.adapterFor(record.constructor);
9407
9992
  var operation;
9408
9993
 
@@ -9574,7 +10159,7 @@
9574
10159
  return factory;
9575
10160
  },
9576
10161
 
9577
- modelFactoryFor: function(key){
10162
+ modelFactoryFor: function(key) {
9578
10163
  return this.container.lookupFactory('model:' + key);
9579
10164
  },
9580
10165
 
@@ -9652,15 +10237,15 @@
9652
10237
  var type = this.modelFor(typeName);
9653
10238
  var filter = Ember.EnumerableUtils.filter;
9654
10239
 
9655
- // If the payload contains unused keys log a warning.
9656
- // Adding `Ember.ENV.DS_NO_WARN_ON_UNUSED_KEYS = true` will suppress the warning.
9657
- if (!Ember.ENV.DS_NO_WARN_ON_UNUSED_KEYS) {
10240
+ // If Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS is set to true and the payload
10241
+ // contains unknown keys, log a warning.
10242
+ if (Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS) {
9658
10243
  Ember.warn("The payload for '" + type.typeKey + "' contains these unknown keys: " +
9659
10244
  Ember.inspect(filter(Ember.keys(data), function(key) {
9660
- return !ember$data$lib$system$store$$get(type, 'fields').has(key) && key !== 'id' && key !== 'links';
10245
+ return !(key === 'id' || key === 'links' || ember$data$lib$system$store$$get(type, 'fields').has(key) || key.match(/Type$/));
9661
10246
  })) + ". Make sure they've been defined in your model.",
9662
10247
  filter(Ember.keys(data), function(key) {
9663
- return !ember$data$lib$system$store$$get(type, 'fields').has(key) && key !== 'id' && key !== 'links';
10248
+ return !(key === 'id' || key === 'links' || ember$data$lib$system$store$$get(type, 'fields').has(key) || key.match(/Type$/));
9664
10249
  }).length === 0
9665
10250
  );
9666
10251
  }
@@ -9865,19 +10450,35 @@
9865
10450
  return record;
9866
10451
  },
9867
10452
 
10453
+ //Called by the state machine to notify the store that the record is ready to be interacted with
10454
+ recordWasLoaded: function(record) {
10455
+ this.recordArrayManager.recordWasLoaded(record);
10456
+ },
10457
+
9868
10458
  // ...............
9869
10459
  // . DESTRUCTION .
9870
10460
  // ...............
9871
10461
 
10462
+ /**
10463
+ @method dematerializeRecord
10464
+ @private
10465
+ @param {DS.Model} record
10466
+ @deprecated Use [unloadRecord](#method_unloadRecord) instead
10467
+ */
10468
+ dematerializeRecord: function(record) {
10469
+ Ember.deprecate('Using store.dematerializeRecord() has been deprecated since it was intended for private use only. You should use store.unloadRecord() instead.');
10470
+ this._dematerializeRecord(record);
10471
+ },
10472
+
9872
10473
  /**
9873
10474
  When a record is destroyed, this un-indexes it and
9874
10475
  removes it from any record arrays so it can be GCed.
9875
10476
 
9876
- @method dematerializeRecord
10477
+ @method _dematerializeRecord
9877
10478
  @private
9878
10479
  @param {DS.Model} record
9879
10480
  */
9880
- dematerializeRecord: function(record) {
10481
+ _dematerializeRecord: function(record) {
9881
10482
  var type = record.constructor;
9882
10483
  var typeMap = this.typeMapFor(type);
9883
10484
  var id = ember$data$lib$system$store$$get(record, 'id');
@@ -9905,7 +10506,8 @@
9905
10506
  @return DS.Adapter
9906
10507
  */
9907
10508
  adapterFor: function(type) {
9908
- var container = this.container, adapter;
10509
+ var adapter;
10510
+ var container = this.container;
9909
10511
 
9910
10512
  if (container) {
9911
10513
  adapter = container.lookup('adapter:' + type.typeKey) || container.lookup('adapter:application');
@@ -9999,8 +10601,8 @@
9999
10601
  type = ember$data$lib$system$store$$typeFor(relationship, key, data);
10000
10602
  data[key] = store.recordForId(type, id);
10001
10603
  } else if (typeof id === 'object') {
10002
- // polymorphic
10003
- Ember.assert('Ember Data expected a number or string to represent the record(s) in the `' + relationship.key + '` relationship instead it found an object. If this is a polymorphic relationship please specify a `type` key. If this is an embedded relationship please include the `DS.EmbeddedRecordsMixin` and specify the `' + relationship.key +'` property in your serializer\'s attrs hash.', id.type);
10604
+ // hasMany polymorphic
10605
+ Ember.assert('Ember Data expected a number or string to represent the record(s) in the `' + relationship.key + '` relationship instead it found an object. If this is a polymorphic relationship please specify a `type` key. If this is an embedded relationship please include the `DS.EmbeddedRecordsMixin` and specify the `' + relationship.key +'` property in your serializer\'s attrs object.', id.type);
10004
10606
  data[key] = store.recordForId(id.type, id.id);
10005
10607
  }
10006
10608
  }
@@ -10102,6 +10704,9 @@
10102
10704
  var record = store.getById(type, id);
10103
10705
  if (record) {
10104
10706
  record.notFound();
10707
+ if (ember$data$lib$system$store$$get(record, 'isEmpty')) {
10708
+ store.unloadRecord(record);
10709
+ }
10105
10710
  }
10106
10711
  throw error;
10107
10712
  }, "DS: Extract payload of '" + type + "'");
@@ -10275,13 +10880,13 @@
10275
10880
  }
10276
10881
  relationship.setCanonicalRecord(value);
10277
10882
  } else if (kind === 'hasMany' && value) {
10278
- relationship.updateRecordsFromAdapter(value);
10883
+ relationship.updateRecordsFromAdapter(value);
10279
10884
  }
10280
10885
  });
10281
10886
  }
10282
10887
 
10283
10888
  var ember$data$lib$system$store$$default = ember$data$lib$system$store$$Store;
10284
- function ember$data$lib$initializers$store$$initializeStore(container, application){
10889
+ function ember$data$lib$initializers$store$$initializeStore(container, application) {
10285
10890
  Ember.deprecate('Specifying a custom Store for Ember Data on your global namespace as `App.Store` ' +
10286
10891
  'has been deprecated. Please use `App.ApplicationStore` instead.', !(application && application.Store));
10287
10892
 
@@ -10388,11 +10993,11 @@
10388
10993
  }
10389
10994
 
10390
10995
  return this.getUTCFullYear() +
10391
- '-' + pad( this.getUTCMonth() + 1 ) +
10392
- '-' + pad( this.getUTCDate() ) +
10393
- 'T' + pad( this.getUTCHours() ) +
10394
- ':' + pad( this.getUTCMinutes() ) +
10395
- ':' + pad( this.getUTCSeconds() ) +
10996
+ '-' + pad(this.getUTCMonth() + 1) +
10997
+ '-' + pad(this.getUTCDate()) +
10998
+ 'T' + pad(this.getUTCHours()) +
10999
+ ':' + pad(this.getUTCMinutes()) +
11000
+ ':' + pad(this.getUTCSeconds()) +
10396
11001
  '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
10397
11002
  'Z';
10398
11003
  };
@@ -10460,17 +11065,17 @@
10460
11065
  }
10461
11066
  });
10462
11067
 
10463
- function ember$data$lib$initializers$transforms$$initializeTransforms(container){
11068
+ function ember$data$lib$initializers$transforms$$initializeTransforms(container) {
10464
11069
  container.register('transform:boolean', ember$data$lib$transforms$boolean$$default);
10465
- container.register('transform:date', ember$data$lib$transforms$date$$default);
10466
- container.register('transform:number', ember$data$lib$transforms$number$$default);
10467
- container.register('transform:string', ember$data$lib$transforms$string$$default);
11070
+ container.register('transform:date', ember$data$lib$transforms$date$$default);
11071
+ container.register('transform:number', ember$data$lib$transforms$number$$default);
11072
+ container.register('transform:string', ember$data$lib$transforms$string$$default);
10468
11073
  }
10469
11074
  var ember$data$lib$initializers$transforms$$default = ember$data$lib$initializers$transforms$$initializeTransforms;
10470
- function ember$data$lib$initializers$store_injections$$initializeStoreInjections(container){
10471
- container.injection('controller', 'store', 'store:main');
10472
- container.injection('route', 'store', 'store:main');
10473
- container.injection('serializer', 'store', 'store:main');
11075
+ function ember$data$lib$initializers$store_injections$$initializeStoreInjections(container) {
11076
+ container.injection('controller', 'store', 'store:main');
11077
+ container.injection('route', 'store', 'store:main');
11078
+ container.injection('serializer', 'store', 'store:main');
10474
11079
  container.injection('data-adapter', 'store', 'store:main');
10475
11080
  }
10476
11081
  var ember$data$lib$initializers$store_injections$$default = ember$data$lib$initializers$store_injections$$initializeStoreInjections;
@@ -10499,9 +11104,9 @@
10499
11104
  var count = 0;
10500
11105
  var self = this;
10501
11106
  ember$data$lib$system$debug$debug_adapter$$get(type, 'attributes').forEach(function(meta, name) {
10502
- if (count++ > self.attributeLimit) { return false; }
10503
- var desc = ember$data$lib$system$debug$debug_adapter$$capitalize(ember$data$lib$system$debug$debug_adapter$$underscore(name).replace('_', ' '));
10504
- columns.push({ name: name, desc: desc });
11107
+ if (count++ > self.attributeLimit) { return false; }
11108
+ var desc = ember$data$lib$system$debug$debug_adapter$$capitalize(ember$data$lib$system$debug$debug_adapter$$underscore(name).replace('_', ' '));
11109
+ columns.push({ name: name, desc: desc });
10505
11110
  });
10506
11111
  return columns;
10507
11112
  },
@@ -10511,7 +11116,8 @@
10511
11116
  },
10512
11117
 
10513
11118
  getRecordColumnValues: function(record) {
10514
- var self = this, count = 0;
11119
+ var self = this;
11120
+ var count = 0;
10515
11121
  var columnValues = { id: ember$data$lib$system$debug$debug_adapter$$get(record, 'id') };
10516
11122
 
10517
11123
  record.eachAttribute(function(key) {
@@ -10555,7 +11161,8 @@
10555
11161
  },
10556
11162
 
10557
11163
  observeRecord: function(record, recordUpdated) {
10558
- var releaseMethods = Ember.A(), self = this;
11164
+ var releaseMethods = Ember.A();
11165
+ var self = this;
10559
11166
  var keysToObserve = Ember.A(['id', 'isNew', 'isDirty']);
10560
11167
 
10561
11168
  record.eachAttribute(function(key) {
@@ -10581,11 +11188,11 @@
10581
11188
 
10582
11189
  });
10583
11190
 
10584
- function ember$data$lib$initializers$data_adapter$$initializeDebugAdapter(container){
11191
+ function ember$data$lib$initializers$data_adapter$$initializeDebugAdapter(container) {
10585
11192
  container.register('data-adapter:main', ember$data$lib$system$debug$debug_adapter$$default);
10586
11193
  }
10587
11194
  var ember$data$lib$initializers$data_adapter$$default = ember$data$lib$initializers$data_adapter$$initializeDebugAdapter;
10588
- function ember$data$lib$setup$container$$setupContainer(container, application){
11195
+ function ember$data$lib$setup$container$$setupContainer(container, application) {
10589
11196
  // application is not a required argument. This ensures
10590
11197
  // testing setups can setup a container without booting an
10591
11198
  // entire ember application.
@@ -10692,7 +11299,8 @@
10692
11299
  */
10693
11300
  Ember.Date = Ember.Date || {};
10694
11301
 
10695
- var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ];
11302
+ var origParse = Date.parse;
11303
+ var numericKeys = [1, 4, 5, 6, 7, 10, 11];
10696
11304
 
10697
11305
  /**
10698
11306
  @method parse
@@ -10700,51 +11308,42 @@
10700
11308
  @return {Number} timestamp
10701
11309
  */
10702
11310
  Ember.Date.parse = function (date) {
10703
- var timestamp, struct, minutesOffset = 0;
10704
-
10705
- // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
10706
- // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
10707
- // implementations could be faster
10708
- // 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm
10709
- if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) {
10710
- // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
10711
- for (var i = 0, k; (k = numericKeys[i]); ++i) {
10712
- struct[k] = +struct[k] || 0;
10713
- }
11311
+ var timestamp, struct;
11312
+ var minutesOffset = 0;
10714
11313
 
10715
- // allow undefined days and months
10716
- struct[2] = (+struct[2] || 1) - 1;
10717
- struct[3] = +struct[3] || 1;
11314
+ // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
11315
+ // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
11316
+ // implementations could be faster
11317
+ // 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm
11318
+ if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) {
11319
+ // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
11320
+ for (var i = 0, k; (k = numericKeys[i]); ++i) {
11321
+ struct[k] = +struct[k] || 0;
11322
+ }
10718
11323
 
10719
- if (struct[8] !== 'Z' && struct[9] !== undefined) {
10720
- minutesOffset = struct[10] * 60 + struct[11];
11324
+ // allow undefined days and months
11325
+ struct[2] = (+struct[2] || 1) - 1;
11326
+ struct[3] = +struct[3] || 1;
10721
11327
 
10722
- if (struct[9] === '+') {
10723
- minutesOffset = 0 - minutesOffset;
10724
- }
10725
- }
11328
+ if (struct[8] !== 'Z' && struct[9] !== undefined) {
11329
+ minutesOffset = struct[10] * 60 + struct[11];
10726
11330
 
10727
- timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
10728
- }
10729
- else {
10730
- timestamp = origParse ? origParse(date) : NaN;
11331
+ if (struct[9] === '+') {
11332
+ minutesOffset = 0 - minutesOffset;
11333
+ }
10731
11334
  }
10732
11335
 
10733
- return timestamp;
11336
+ timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
11337
+ } else {
11338
+ timestamp = origParse ? origParse(date) : NaN;
11339
+ }
11340
+
11341
+ return timestamp;
10734
11342
  };
10735
11343
 
10736
11344
  if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
10737
11345
  Date.parse = Ember.Date.parse;
10738
11346
  }
10739
- /*
10740
- Detect if the user has a correct Object.create shim.
10741
- Ember has provided this for a long time but has had an incorrect shim before 1.8
10742
- TODO: Remove for Ember Data 1.0.
10743
- */
10744
- var object = Ember.create(null);
10745
- if (object.toString !== undefined && Ember.keys(Ember.create({}))[0] === '__proto__'){
10746
- throw new Error("Ember Data requires a correct Object.create shim. You should upgrade to Ember >= 1.8 which provides one for you. If you are using ES5-shim, you should try removing that after upgrading Ember.");
10747
- }
10748
11347
 
10749
11348
  ember$data$lib$system$model$model$$default.reopen({
10750
11349
 
@@ -10765,9 +11364,9 @@
10765
11364
  @private
10766
11365
  */
10767
11366
  _debugInfo: function() {
10768
- var attributes = ['id'],
10769
- relationships = { belongsTo: [], hasMany: [] },
10770
- expensiveProperties = [];
11367
+ var attributes = ['id'];
11368
+ var relationships = { belongsTo: [], hasMany: [] };
11369
+ var expensiveProperties = [];
10771
11370
 
10772
11371
  this.eachAttribute(function(name, meta) {
10773
11372
  attributes.push(name);
@@ -10845,7 +11444,7 @@
10845
11444
  The `attrs` option for a resource `{ embedded: 'always' }` is shorthand for:
10846
11445
 
10847
11446
  ```js
10848
- {
11447
+ {
10849
11448
  serialize: 'records',
10850
11449
  deserialize: 'records'
10851
11450
  }
@@ -10872,7 +11471,7 @@
10872
11471
  If you do not overwrite `attrs` for a specific relationship, the `EmbeddedRecordsMixin`
10873
11472
  will behave in the following way:
10874
11473
 
10875
- BelongsTo: `{ serialize: 'id', deserialize: 'id' }`
11474
+ BelongsTo: `{ serialize: 'id', deserialize: 'id' }`
10876
11475
  HasMany: `{ serialize: false, deserialize: 'ids' }`
10877
11476
 
10878
11477
  ### Model Relationships
@@ -10939,7 +11538,7 @@
10939
11538
  return ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedRecords(this, this.store, type, normalizedHash);
10940
11539
  },
10941
11540
 
10942
- keyForRelationship: function(key, type){
11541
+ keyForRelationship: function(key, type) {
10943
11542
  if (this.hasDeserializeRecordsOption(key)) {
10944
11543
  return this.keyForAttribute(key);
10945
11544
  } else {
@@ -10992,34 +11591,34 @@
10992
11591
  ```
10993
11592
 
10994
11593
  @method serializeBelongsTo
10995
- @param {DS.Model} record
11594
+ @param {DS.Snapshot} snapshot
10996
11595
  @param {Object} json
10997
11596
  @param {Object} relationship
10998
11597
  */
10999
- serializeBelongsTo: function(record, json, relationship) {
11598
+ serializeBelongsTo: function(snapshot, json, relationship) {
11000
11599
  var attr = relationship.key;
11001
11600
  if (this.noSerializeOptionSpecified(attr)) {
11002
- this._super(record, json, relationship);
11601
+ this._super(snapshot, json, relationship);
11003
11602
  return;
11004
11603
  }
11005
11604
  var includeIds = this.hasSerializeIdsOption(attr);
11006
11605
  var includeRecords = this.hasSerializeRecordsOption(attr);
11007
- var embeddedRecord = record.get(attr);
11606
+ var embeddedSnapshot = snapshot.belongsTo(attr);
11008
11607
  var key;
11009
11608
  if (includeIds) {
11010
11609
  key = this.keyForRelationship(attr, relationship.kind);
11011
- if (!embeddedRecord) {
11610
+ if (!embeddedSnapshot) {
11012
11611
  json[key] = null;
11013
11612
  } else {
11014
- json[key] = ember$data$lib$serializers$embedded_records_mixin$$get(embeddedRecord, 'id');
11613
+ json[key] = embeddedSnapshot.id;
11015
11614
  }
11016
11615
  } else if (includeRecords) {
11017
11616
  key = this.keyForAttribute(attr);
11018
- if (!embeddedRecord) {
11617
+ if (!embeddedSnapshot) {
11019
11618
  json[key] = null;
11020
11619
  } else {
11021
- json[key] = embeddedRecord.serialize({includeId: true});
11022
- this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, json[key]);
11620
+ json[key] = embeddedSnapshot.record.serialize({ includeId: true });
11621
+ this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, json[key]);
11023
11622
  }
11024
11623
  }
11025
11624
  },
@@ -11101,14 +11700,14 @@
11101
11700
  ```
11102
11701
 
11103
11702
  @method serializeHasMany
11104
- @param {DS.Model} record
11703
+ @param {DS.Snapshot} snapshot
11105
11704
  @param {Object} json
11106
11705
  @param {Object} relationship
11107
11706
  */
11108
- serializeHasMany: function(record, json, relationship) {
11707
+ serializeHasMany: function(snapshot, json, relationship) {
11109
11708
  var attr = relationship.key;
11110
11709
  if (this.noSerializeOptionSpecified(attr)) {
11111
- this._super(record, json, relationship);
11710
+ this._super(snapshot, json, relationship);
11112
11711
  return;
11113
11712
  }
11114
11713
  var includeIds = this.hasSerializeIdsOption(attr);
@@ -11116,13 +11715,13 @@
11116
11715
  var key;
11117
11716
  if (includeIds) {
11118
11717
  key = this.keyForRelationship(attr, relationship.kind);
11119
- json[key] = ember$data$lib$serializers$embedded_records_mixin$$get(record, attr).mapBy('id');
11718
+ json[key] = snapshot.hasMany(attr, { ids: true });
11120
11719
  } else if (includeRecords) {
11121
11720
  key = this.keyForAttribute(attr);
11122
- json[key] = ember$data$lib$serializers$embedded_records_mixin$$get(record, attr).map(function(embeddedRecord) {
11123
- var serializedEmbeddedRecord = embeddedRecord.serialize({includeId: true});
11124
- this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, serializedEmbeddedRecord);
11125
- return serializedEmbeddedRecord;
11721
+ json[key] = snapshot.hasMany(attr).map(function(embeddedSnapshot) {
11722
+ var embeddedJson = embeddedSnapshot.record.serialize({ includeId: true });
11723
+ this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, embeddedJson);
11724
+ return embeddedJson;
11126
11725
  }, this);
11127
11726
  }
11128
11727
  },
@@ -11138,19 +11737,19 @@
11138
11737
  the parent record.
11139
11738
 
11140
11739
  @method removeEmbeddedForeignKey
11141
- @param {DS.Model} record
11142
- @param {DS.Model} embeddedRecord
11740
+ @param {DS.Snapshot} snapshot
11741
+ @param {DS.Snapshot} embeddedSnapshot
11143
11742
  @param {Object} relationship
11144
11743
  @param {Object} json
11145
11744
  */
11146
- removeEmbeddedForeignKey: function (record, embeddedRecord, relationship, json) {
11745
+ removeEmbeddedForeignKey: function (snapshot, embeddedSnapshot, relationship, json) {
11147
11746
  if (relationship.kind === 'hasMany') {
11148
11747
  return;
11149
11748
  } else if (relationship.kind === 'belongsTo') {
11150
- var parentRecord = record.constructor.inverseFor(relationship.key);
11749
+ var parentRecord = snapshot.type.inverseFor(relationship.key);
11151
11750
  if (parentRecord) {
11152
11751
  var name = parentRecord.name;
11153
- var embeddedSerializer = this.store.serializerFor(embeddedRecord.constructor);
11752
+ var embeddedSerializer = this.store.serializerFor(embeddedSnapshot.type);
11154
11753
  var parentKey = embeddedSerializer.keyForRelationship(name, parentRecord.kind);
11155
11754
  if (parentKey) {
11156
11755
  delete json[parentKey];
@@ -11209,13 +11808,16 @@
11209
11808
  if (relationship.kind === "hasMany") {
11210
11809
  if (relationship.options.polymorphic) {
11211
11810
  ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedHasManyPolymorphic(store, key, partial);
11212
- }
11213
- else {
11811
+ } else {
11214
11812
  ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedHasMany(store, key, embeddedType, partial);
11215
11813
  }
11216
11814
  }
11217
11815
  if (relationship.kind === "belongsTo") {
11218
- ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedBelongsTo(store, key, embeddedType, partial);
11816
+ if (relationship.options.polymorphic) {
11817
+ ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedBelongsToPolymorphic(store, key, partial);
11818
+ } else {
11819
+ ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedBelongsTo(store, key, embeddedType, partial);
11820
+ }
11219
11821
  }
11220
11822
  }
11221
11823
  });
@@ -11278,8 +11880,26 @@
11278
11880
  return hash;
11279
11881
  }
11280
11882
 
11281
- var ember$data$lib$serializers$embedded_records_mixin$$default = ember$data$lib$serializers$embedded_records_mixin$$EmbeddedRecordsMixin;
11883
+ function ember$data$lib$serializers$embedded_records_mixin$$extractEmbeddedBelongsToPolymorphic(store, key, hash) {
11884
+ if (!hash[key]) {
11885
+ return hash;
11886
+ }
11282
11887
 
11888
+ var data = hash[key];
11889
+ var typeKey = data.type;
11890
+ var embeddedSerializer = store.serializerFor(typeKey);
11891
+ var embeddedType = store.modelFor(typeKey);
11892
+ var primaryKey = ember$data$lib$serializers$embedded_records_mixin$$get(embeddedSerializer, 'primaryKey');
11893
+
11894
+ var embeddedRecord = embeddedSerializer.normalize(embeddedType, data, null);
11895
+ store.push(embeddedType, embeddedRecord);
11896
+
11897
+ hash[key] = embeddedRecord[primaryKey];
11898
+ hash[key + 'Type'] = typeKey;
11899
+ return hash;
11900
+ }
11901
+
11902
+ var ember$data$lib$serializers$embedded_records_mixin$$default = ember$data$lib$serializers$embedded_records_mixin$$EmbeddedRecordsMixin;
11283
11903
 
11284
11904
  /**
11285
11905
  `DS.belongsTo` is used to define One-To-One and One-To-Many
@@ -11345,7 +11965,7 @@
11345
11965
  type = undefined;
11346
11966
  }
11347
11967
 
11348
- Ember.assert("The first argument to DS.belongsTo must be a string representing a model type key, not an instance of " + Ember.inspect(type) + ". E.g., to define a relation to the Person model, use DS.belongsTo('person')", typeof type === 'string' || typeof type === 'undefined');
11968
+ Ember.assert("The first argument to DS.belongsTo must be a string representing a model type key, not an instance of " + Ember.inspect(type) + ". E.g., to define a relation to the Person model, use DS.belongsTo('person')", typeof type === 'string' || typeof type === 'undefined');
11349
11969
 
11350
11970
  options = options || {};
11351
11971
 
@@ -11373,12 +11993,9 @@
11373
11993
  }).meta(meta);
11374
11994
  }
11375
11995
 
11376
- /**
11996
+ /*
11377
11997
  These observers observe all `belongsTo` relationships on the record. See
11378
11998
  `relationships/ext` to see how these observers get their dependencies.
11379
-
11380
- @class Model
11381
- @namespace DS
11382
11999
  */
11383
12000
  ember$data$lib$system$model$model$$default.reopen({
11384
12001
  notifyBelongsToChanged: function(key) {
@@ -11483,7 +12100,7 @@
11483
12100
  type = undefined;
11484
12101
  }
11485
12102
 
11486
- Ember.assert("The first argument to DS.hasMany must be a string representing a model type key, not an instance of " + Ember.inspect(type) + ". E.g., to define a relation to the Comment model, use DS.hasMany('comment')", typeof type === 'string' || typeof type === 'undefined');
12103
+ Ember.assert("The first argument to DS.hasMany must be a string representing a model type key, not an instance of " + Ember.inspect(type) + ". E.g., to define a relation to the Comment model, use DS.hasMany('comment')", typeof type === 'string' || typeof type === 'undefined');
11487
12104
 
11488
12105
  options = options || {};
11489
12106
 
@@ -11513,7 +12130,7 @@
11513
12130
 
11514
12131
  //Goes away once hasMany is double promisified
11515
12132
  this.notifyPropertyChange(key);
11516
- },
12133
+ }
11517
12134
  });
11518
12135
 
11519
12136
 
@@ -11549,30 +12166,30 @@
11549
12166
  var ember$data$lib$system$relationships$ext$$filter = Ember.ArrayPolyfills.filter;
11550
12167
 
11551
12168
  var ember$data$lib$system$relationships$ext$$relationshipsDescriptor = Ember.computed(function() {
11552
- if (Ember.testing === true && ember$data$lib$system$relationships$ext$$relationshipsDescriptor._cacheable === true) {
11553
- ember$data$lib$system$relationships$ext$$relationshipsDescriptor._cacheable = false;
11554
- }
12169
+ if (Ember.testing === true && ember$data$lib$system$relationships$ext$$relationshipsDescriptor._cacheable === true) {
12170
+ ember$data$lib$system$relationships$ext$$relationshipsDescriptor._cacheable = false;
12171
+ }
11555
12172
 
11556
- var map = new ember$data$lib$system$map$$MapWithDefault({
11557
- defaultValue: function() { return []; }
11558
- });
12173
+ var map = new ember$data$lib$system$map$$MapWithDefault({
12174
+ defaultValue: function() { return []; }
12175
+ });
11559
12176
 
11560
- // Loop through each computed property on the class
11561
- this.eachComputedProperty(function(name, meta) {
11562
- // If the computed property is a relationship, add
11563
- // it to the map.
11564
- if (meta.isRelationship) {
11565
- meta.key = name;
11566
- var relationshipsForType = map.get(ember$data$lib$system$relationship$meta$$typeForRelationshipMeta(this.store, meta));
12177
+ // Loop through each computed property on the class
12178
+ this.eachComputedProperty(function(name, meta) {
12179
+ // If the computed property is a relationship, add
12180
+ // it to the map.
12181
+ if (meta.isRelationship) {
12182
+ meta.key = name;
12183
+ var relationshipsForType = map.get(ember$data$lib$system$relationship$meta$$typeForRelationshipMeta(this.store, meta));
11567
12184
 
11568
- relationshipsForType.push({
11569
- name: name,
11570
- kind: meta.kind
11571
- });
11572
- }
11573
- });
12185
+ relationshipsForType.push({
12186
+ name: name,
12187
+ kind: meta.kind
12188
+ });
12189
+ }
12190
+ });
11574
12191
 
11575
- return map;
12192
+ return map;
11576
12193
  }).readOnly();
11577
12194
 
11578
12195
  var ember$data$lib$system$relationships$ext$$relatedTypesDescriptor = Ember.computed(function() {
@@ -11591,7 +12208,7 @@
11591
12208
  meta.key = name;
11592
12209
  type = ember$data$lib$system$relationship$meta$$typeForRelationshipMeta(this.store, meta);
11593
12210
 
11594
- Ember.assert("You specified a hasMany (" + meta.type + ") on " + meta.parentType + " but " + meta.type + " was not found.", type);
12211
+ Ember.assert("You specified a hasMany (" + meta.type + ") on " + meta.parentType + " but " + meta.type + " was not found.", type);
11595
12212
 
11596
12213
  if (!types.contains(type)) {
11597
12214
  Ember.assert("Trying to sideload " + name + " on " + this.toString() + " but the type doesn't exist.", !!type);
@@ -11765,12 +12382,15 @@
11765
12382
  return null;
11766
12383
  }
11767
12384
 
12385
+ var propertyMeta = this.metaForProperty(name);
11768
12386
  //If inverse is manually specified to be null, like `comments: DS.hasMany('message', {inverse: null})`
11769
- var options = this.metaForProperty(name).options;
12387
+ var options = propertyMeta.options;
11770
12388
  if (options.inverse === null) { return null; }
11771
12389
 
11772
12390
  var inverseName, inverseKind, inverse;
11773
12391
 
12392
+ Ember.warn("Detected a reflexive relationship by the name of '" + name + "' without an inverse option. Look at http://emberjs.com/guides/models/defining-models/#toc_reflexive-relation for how to explicitly specify inverses.", options.inverse || propertyMeta.type !== propertyMeta.parentType.typeKey);
12393
+
11774
12394
  //If inverse is specified manually, return the inverse
11775
12395
  if (options.inverse) {
11776
12396
  inverseName = options.inverse;
@@ -11818,7 +12438,7 @@
11818
12438
  relationships = ember$data$lib$system$relationships$ext$$filter.call(relationships, function(relationship) {
11819
12439
  var optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
11820
12440
 
11821
- if (!optionsForRelationship.inverse){
12441
+ if (!optionsForRelationship.inverse) {
11822
12442
  return true;
11823
12443
  }
11824
12444
 
@@ -12097,6 +12717,47 @@
12097
12717
  invoking the callback with the name of each relationship and its relationship
12098
12718
  descriptor.
12099
12719
 
12720
+
12721
+ The callback method you provide should have the following signature (all
12722
+ parameters are optional):
12723
+
12724
+ ```javascript
12725
+ function(name, descriptor);
12726
+ ```
12727
+
12728
+ - `name` the name of the current property in the iteration
12729
+ - `descriptor` the meta object that describes this relationship
12730
+
12731
+ The relationship descriptor argument is an object with the following properties.
12732
+
12733
+ - **key** <span class="type">String</span> the name of this relationship on the Model
12734
+ - **kind** <span class="type">String</span> "hasMany" or "belongsTo"
12735
+ - **options** <span class="type">Object</span> the original options hash passed when the relationship was declared
12736
+ - **parentType** <span class="type">DS.Model</span> the type of the Model that owns this relationship
12737
+ - **type** <span class="type">DS.Model</span> the type of the related Model
12738
+
12739
+ Note that in addition to a callback, you can also pass an optional target
12740
+ object that will be set as `this` on the context.
12741
+
12742
+ Example
12743
+
12744
+ ```javascript
12745
+ App.ApplicationSerializer = DS.JSONSerializer.extend({
12746
+ serialize: function(record, options) {
12747
+ var json = {};
12748
+
12749
+ record.eachRelationship(function(name, descriptor) {
12750
+ if (descriptor.kind === 'hasMany') {
12751
+ var serializedHasManyName = name.toUpperCase() + '_IDS';
12752
+ json[name.toUpperCase()] = record.get(name).mapBy('id');
12753
+ }
12754
+ });
12755
+
12756
+ return json;
12757
+ }
12758
+ });
12759
+ ```
12760
+
12100
12761
  @method eachRelationship
12101
12762
  @param {Function} callback the callback to invoke
12102
12763
  @param {any} binding the value to which the callback's `this` should be bound
@@ -12123,8 +12784,8 @@
12123
12784
  // support RSVP 2.x via resolve, but prefer RSVP 3.x's Promise.cast
12124
12785
  Ember.RSVP.Promise.cast = Ember.RSVP.Promise.cast || Ember.RSVP.resolve;
12125
12786
 
12126
- Ember.runInDebug(function(){
12127
- if (Ember.VERSION.match(/1\.[0-7]\./)){
12787
+ Ember.runInDebug(function() {
12788
+ if (Ember.VERSION.match(/1\.[0-7]\./)) {
12128
12789
  throw new Ember.Error("Ember Data requires at least Ember 1.8.0, but you have " +
12129
12790
  Ember.VERSION +
12130
12791
  ". Please upgrade your version of Ember, then upgrade Ember Data");
@@ -12142,9 +12803,13 @@
12142
12803
  ember$data$lib$core$$default.attr = ember$data$lib$system$model$attributes$$default;
12143
12804
  ember$data$lib$core$$default.Errors = ember$data$lib$system$model$errors$$default;
12144
12805
 
12806
+ ember$data$lib$core$$default.Snapshot = ember$data$lib$system$snapshot$$default;
12807
+
12145
12808
  ember$data$lib$core$$default.Adapter = ember$data$lib$system$adapter$$Adapter;
12146
12809
  ember$data$lib$core$$default.InvalidError = ember$data$lib$system$adapter$$InvalidError;
12147
12810
 
12811
+ ember$data$lib$core$$default.Serializer = ember$data$lib$system$serializer$$default;
12812
+
12148
12813
  ember$data$lib$core$$default.DebugAdapter = ember$data$lib$system$debug$$default;
12149
12814
 
12150
12815
  ember$data$lib$core$$default.RecordArray = ember$data$lib$system$record_arrays$record_array$$default;