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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;