http://git-wip-us.apache.org/repos/asf/ambari/blob/ec8deeba/contrib/views/slider/src/main/resources/ui/vendor/scripts/production/ember-data.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/vendor/scripts/production/ember-data.js b/contrib/views/slider/src/main/resources/ui/vendor/scripts/production/ember-data.js deleted file mode 100644 index d6a58cb..0000000 --- a/contrib/views/slider/src/main/resources/ui/vendor/scripts/production/ember-data.js +++ /dev/null @@ -1,10626 +0,0 @@ -/*! - * @overview Ember Data - * @copyright Copyright 2011-2014 Tilde Inc. and contributors. - * Portions Copyright 2011 LivingSocial Inc. - * @license Licensed under MIT license (see license.js) - * @version 1.0.0-beta.7+canary.238bb5ce - */ - - -(function() { -var define, requireModule; - -(function() { - var registry = {}, seen = {}; - - define = function(name, deps, callback) { - registry[name] = { deps: deps, callback: callback }; - }; - - requireModule = function(name) { - if (seen[name]) { return seen[name]; } - seen[name] = {}; - - var mod, deps, callback, reified , exports; - - mod = registry[name]; - - if (!mod) { - throw new Error("Module '" + name + "' not found."); - } - - deps = mod.deps; - callback = mod.callback; - reified = []; - exports; - - for (var i=0, l=deps.length; i<l; i++) { - if (deps[i] === 'exports') { - reified.push(exports = {}); - } else { - reified.push(requireModule(deps[i])); - } - } - - var value = callback.apply(this, reified); - return seen[name] = exports || value; - }; -})(); -(function() { -/** - @module ember-data -*/ - -/** - All Ember Data methods and functions are defined inside of this namespace. - - @class DS - @static -*/ -var DS; -if ('undefined' === typeof DS) { - /** - @property VERSION - @type String - @default '1.0.0-beta.7+canary.238bb5ce' - @static - */ - DS = Ember.Namespace.create({ - VERSION: '1.0.0-beta.7+canary.238bb5ce' - }); - - if ('undefined' !== typeof window) { - window.DS = DS; - } - - if (Ember.libraries) { - Ember.libraries.registerCoreLibrary('Ember Data', DS.VERSION); - } -} - -})(); - - - -(function() { -/** - This is used internally to enable deprecation of container paths and provide - a decent message to the user indicating how to fix the issue. - - @class ContainerProxy - @namespace DS - @private -*/ -var ContainerProxy = function (container){ - this.container = container; -}; - -ContainerProxy.prototype.aliasedFactory = function(path, preLookup) { - var _this = this; - - return {create: function(){ - if (preLookup) { preLookup(); } - - return _this.container.lookup(path); - }}; -}; - -ContainerProxy.prototype.registerAlias = function(source, dest, preLookup) { - var factory = this.aliasedFactory(dest, preLookup); - - return this.container.register(source, factory); -}; - -ContainerProxy.prototype.registerDeprecation = function(deprecated, valid) { - var preLookupCallback = function(){ - Ember.deprecate("You tried to look up '" + deprecated + "', " + - "but this has been deprecated in favor of '" + valid + "'.", false); - }; - - return this.registerAlias(deprecated, valid, preLookupCallback); -}; - -ContainerProxy.prototype.registerDeprecations = function(proxyPairs) { - for (var i = proxyPairs.length; i > 0; i--) { - var proxyPair = proxyPairs[i - 1], - deprecated = proxyPair['deprecated'], - valid = proxyPair['valid']; - - this.registerDeprecation(deprecated, valid); - } -}; - -DS.ContainerProxy = ContainerProxy; - -})(); - - - -(function() { -var get = Ember.get, set = Ember.set, isNone = Ember.isNone; - -// Simple dispatcher to support overriding the aliased -// method in subclasses. -function aliasMethod(methodName) { - return function() { - return this[methodName].apply(this, arguments); - }; -} - -/** - In Ember Data a Serializer is used to serialize and deserialize - records when they are transferred in and out of an external source. - This process involves normalizing property names, transforming - attribute values and serializing relationships. - - For maximum performance Ember Data recommends you use the - [RESTSerializer](DS.RESTSerializer.html) or one of its subclasses. - - `JSONSerializer` is useful for simpler or legacy backends that may - not support the http://jsonapi.org/ spec. - - @class JSONSerializer - @namespace DS -*/ -DS.JSONSerializer = Ember.Object.extend({ - /** - The primaryKey is used when serializing and deserializing - data. Ember Data always uses the `id` property to store the id of - the record. The external source may not always follow this - convention. In these cases it is useful to override the - primaryKey property to match the primaryKey of your external - store. - - Example - - ```javascript - App.ApplicationSerializer = DS.JSONSerializer.extend({ - primaryKey: '_id' - }); - ``` - - @property primaryKey - @type {String} - @default 'id' - */ - primaryKey: 'id', - - /** - Given a subclass of `DS.Model` and a JSON object this method will - iterate through each attribute of the `DS.Model` and invoke the - `DS.Transform#deserialize` method on the matching property of the - JSON object. This method is typically called after the - serializer's `normalize` method. - - @method applyTransforms - @private - @param {subclass of DS.Model} type - @param {Object} data The data to transform - @return {Object} data The transformed data object - */ - applyTransforms: function(type, data) { - type.eachTransformedAttribute(function(key, type) { - var transform = this.transformFor(type); - data[key] = transform.deserialize(data[key]); - }, this); - - return data; - }, - - /** - Normalizes a part of the JSON payload returned by - the server. You should override this method, munge the hash - and call super if you have generic normalization to do. - - It takes the type of the record that is being normalized - (as a DS.Model class), the property where the hash was - originally found, and the hash to normalize. - - You can use this method, for example, to normalize underscored keys to camelized - or other general-purpose normalizations. - - Example - - ```javascript - App.ApplicationSerializer = DS.JSONSerializer.extend({ - normalize: function(type, hash) { - var fields = Ember.get(type, 'fields'); - fields.forEach(function(field) { - var payloadField = Ember.String.underscore(field); - if (field === payloadField) { return; } - - hash[field] = hash[payloadField]; - delete hash[payloadField]; - }); - return this._super.apply(this, arguments); - } - }); - ``` - - @method normalize - @param {subclass of DS.Model} type - @param {Object} hash - @return {Object} - */ - normalize: function(type, hash) { - if (!hash) { return hash; } - - this.applyTransforms(type, hash); - return hash; - }, - - // SERIALIZE - /** - Called when a record is saved in order to convert the - record into JSON. - - By default, it creates a JSON object with a key for - each attribute and belongsTo relationship. - - For example, consider this model: - - ```javascript - App.Comment = DS.Model.extend({ - title: DS.attr(), - body: DS.attr(), - - author: DS.belongsTo('user') - }); - ``` - - The default serialization would create a JSON object like: - - ```javascript - { - "title": "Rails is unagi", - "body": "Rails? Omakase? O_O", - "author": 12 - } - ``` - - By default, attributes are passed through as-is, unless - you specified an attribute type (`DS.attr('date')`). If - you specify a transform, the JavaScript value will be - serialized when inserted into the JSON hash. - - By default, belongs-to relationships are converted into - IDs when inserted into the JSON hash. - - ## IDs - - `serialize` takes an options hash with a single option: - `includeId`. If this option is `true`, `serialize` will, - by default include the ID in the JSON object it builds. - - The adapter passes in `includeId: true` when serializing - a record for `createRecord`, but not for `updateRecord`. - - ## Customization - - Your server may expect a different JSON format than the - built-in serialization format. - - In that case, you can implement `serialize` yourself and - return a JSON hash of your choosing. - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - serialize: function(post, options) { - var json = { - POST_TTL: post.get('title'), - POST_BDY: post.get('body'), - POST_CMS: post.get('comments').mapProperty('id') - } - - if (options.includeId) { - json.POST_ID_ = post.get('id'); - } - - return json; - } - }); - ``` - - ## Customizing an App-Wide Serializer - - If you want to define a serializer for your entire - application, you'll probably want to use `eachAttribute` - and `eachRelationship` on the record. - - ```javascript - App.ApplicationSerializer = DS.JSONSerializer.extend({ - serialize: function(record, options) { - var json = {}; - - record.eachAttribute(function(name) { - json[serverAttributeName(name)] = record.get(name); - }) - - record.eachRelationship(function(name, relationship) { - if (relationship.kind === 'hasMany') { - json[serverHasManyName(name)] = record.get(name).mapBy('id'); - } - }); - - if (options.includeId) { - json.ID_ = record.get('id'); - } - - return json; - } - }); - - function serverAttributeName(attribute) { - return attribute.underscore().toUpperCase(); - } - - function serverHasManyName(name) { - return serverAttributeName(name.singularize()) + "_IDS"; - } - ``` - - This serializer will generate JSON that looks like this: - - ```javascript - { - "TITLE": "Rails is omakase", - "BODY": "Yep. Omakase.", - "COMMENT_IDS": [ 1, 2, 3 ] - } - ``` - - ## Tweaking the Default JSON - - If you just want to do some small tweaks on the default JSON, - you can call super first and make the tweaks on the returned - JSON. - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - serialize: function(record, options) { - var json = this._super.apply(this, arguments); - - json.subject = json.title; - delete json.title; - - return json; - } - }); - ``` - - @method serialize - @param {subclass of DS.Model} record - @param {Object} options - @return {Object} json - */ - serialize: function(record, options) { - var json = {}; - - if (options && options.includeId) { - var id = get(record, 'id'); - - if (id) { - json[get(this, 'primaryKey')] = id; - } - } - - record.eachAttribute(function(key, attribute) { - this.serializeAttribute(record, json, key, attribute); - }, this); - - record.eachRelationship(function(key, relationship) { - if (relationship.kind === 'belongsTo') { - this.serializeBelongsTo(record, json, relationship); - } else if (relationship.kind === 'hasMany') { - this.serializeHasMany(record, json, relationship); - } - }, this); - - return json; - }, - - /** - `serializeAttribute` can be used to customize how `DS.attr` - properties are serialized - - For example if you wanted to ensure all you attributes were always - serialized as properties on an `attributes` object you could - write: - - ```javascript - App.ApplicationSerializer = DS.JSONSerializer.extend({ - serializeAttribute: function(record, json, key, attributes) { - json.attributes = json.attributes || {}; - this._super(record, json.attributes, key, attributes); - } - }); - ``` - - @method serializeAttribute - @param {DS.Model} record - @param {Object} json - @param {String} key - @param {Object} attribute - */ - serializeAttribute: function(record, json, key, attribute) { - var attrs = get(this, 'attrs'); - var value = get(record, key), type = attribute.type; - - if (type) { - var transform = this.transformFor(type); - value = transform.serialize(value); - } - - // if provided, use the mapping provided by `attrs` in - // the serializer - key = attrs && attrs[key] || (this.keyForAttribute ? this.keyForAttribute(key) : key); - - json[key] = value; - }, - - /** - `serializeBelongsTo` can be used to customize how `DS.belongsTo` - properties are serialized. - - Example - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - serializeBelongsTo: function(record, json, relationship) { - var key = relationship.key; - - var belongsTo = get(record, key); - - key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key; - - json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.toJSON(); - } - }); - ``` - - @method serializeBelongsTo - @param {DS.Model} record - @param {Object} json - @param {Object} relationship - */ - serializeBelongsTo: function(record, json, relationship) { - var key = relationship.key; - - var belongsTo = get(record, key); - - key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key; - - if (isNone(belongsTo)) { - json[key] = belongsTo; - } else { - json[key] = get(belongsTo, 'id'); - } - - if (relationship.options.polymorphic) { - this.serializePolymorphicType(record, json, relationship); - } - }, - - /** - `serializeHasMany` can be used to customize how `DS.hasMany` - properties are serialized. - - Example - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - serializeHasMany: function(record, json, relationship) { - var key = relationship.key; - if (key === 'comments') { - return; - } else { - this._super.apply(this, arguments); - } - } - }); - ``` - - @method serializeHasMany - @param {DS.Model} record - @param {Object} json - @param {Object} relationship - */ - serializeHasMany: function(record, json, relationship) { - var key = relationship.key; - - var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship); - - if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') { - json[key] = get(record, key).mapBy('id'); - // TODO support for polymorphic manyToNone and manyToMany relationships - } - }, - - /** - You can use this method to customize how polymorphic objects are - serialized. Objects are considered to be polymorphic if - `{polymorphic: true}` is pass as the second argument to the - `DS.belongsTo` function. - - Example - - ```javascript - App.CommentSerializer = DS.JSONSerializer.extend({ - serializePolymorphicType: function(record, json, relationship) { - var key = relationship.key, - belongsTo = get(record, key); - key = this.keyForAttribute ? this.keyForAttribute(key) : key; - json[key + "_type"] = belongsTo.constructor.typeKey; - } - }); - ``` - - @method serializePolymorphicType - @param {DS.Model} record - @param {Object} json - @param {Object} relationship - */ - serializePolymorphicType: Ember.K, - - // EXTRACT - - /** - The `extract` method is used to deserialize payload data from the - server. By default the `JSONSerializer` does not push the records - into the store. However records that subclass `JSONSerializer` - such as the `RESTSerializer` may push records into the store as - part of the extract call. - - This method delegates to a more specific extract method based on - the `requestType`. - - Example - - ```javascript - var get = Ember.get; - socket.on('message', function(message) { - var modelName = message.model; - var data = message.data; - var type = store.modelFor(modelName); - var serializer = store.serializerFor(type.typeKey); - var record = serializer.extract(store, type, data, get(data, 'id'), 'single'); - store.push(modelName, record); - }); - ``` - - @method extract - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @param {String or Number} id - @param {String} requestType - @return {Object} json The deserialized payload - */ - extract: function(store, type, payload, id, requestType) { - this.extractMeta(store, type, payload); - - var specificExtract = "extract" + requestType.charAt(0).toUpperCase() + requestType.substr(1); - return this[specificExtract](store, type, payload, id, requestType); - }, - - /** - `extractFindAll` is a hook into the extract method used when a - call is made to `DS.Store#findAll`. By default this method is an - alias for [extractArray](#method_extractArray). - - @method extractFindAll - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Array} array An array of deserialized objects - */ - extractFindAll: aliasMethod('extractArray'), - /** - `extractFindQuery` is a hook into the extract method used when a - call is made to `DS.Store#findQuery`. By default this method is an - alias for [extractArray](#method_extractArray). - - @method extractFindQuery - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Array} array An array of deserialized objects - */ - extractFindQuery: aliasMethod('extractArray'), - /** - `extractFindMany` is a hook into the extract method used when a - call is made to `DS.Store#findMany`. By default this method is - alias for [extractArray](#method_extractArray). - - @method extractFindMany - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Array} array An array of deserialized objects - */ - extractFindMany: aliasMethod('extractArray'), - /** - `extractFindHasMany` is a hook into the extract method used when a - call is made to `DS.Store#findHasMany`. By default this method is - alias for [extractArray](#method_extractArray). - - @method extractFindHasMany - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Array} array An array of deserialized objects - */ - extractFindHasMany: aliasMethod('extractArray'), - - /** - `extractCreateRecord` is a hook into the extract method used when a - call is made to `DS.Store#createRecord`. By default this method is - alias for [extractSave](#method_extractSave). - - @method extractCreateRecord - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractCreateRecord: aliasMethod('extractSave'), - /** - `extractUpdateRecord` is a hook into the extract method used when - a call is made to `DS.Store#update`. By default this method is alias - for [extractSave](#method_extractSave). - - @method extractUpdateRecord - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractUpdateRecord: aliasMethod('extractSave'), - /** - `extractDeleteRecord` is a hook into the extract method used when - a call is made to `DS.Store#deleteRecord`. By default this method is - alias for [extractSave](#method_extractSave). - - @method extractDeleteRecord - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractDeleteRecord: aliasMethod('extractSave'), - - /** - `extractFind` is a hook into the extract method used when - a call is made to `DS.Store#find`. By default this method is - alias for [extractSingle](#method_extractSingle). - - @method extractFind - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractFind: aliasMethod('extractSingle'), - /** - `extractFindBelongsTo` is a hook into the extract method used when - a call is made to `DS.Store#findBelongsTo`. By default this method is - alias for [extractSingle](#method_extractSingle). - - @method extractFindBelongsTo - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractFindBelongsTo: aliasMethod('extractSingle'), - /** - `extractSave` is a hook into the extract method used when a call - is made to `DS.Model#save`. By default this method is alias - for [extractSingle](#method_extractSingle). - - @method extractSave - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractSave: aliasMethod('extractSingle'), - - /** - `extractSingle` is used to deserialize a single record returned - from the adapter. - - Example - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - extractSingle: function(store, type, payload) { - payload.comments = payload._embedded.comment; - delete payload._embedded; - - return this._super(store, type, payload); - }, - }); - ``` - - @method extractSingle - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Object} json The deserialized payload - */ - extractSingle: function(store, type, payload) { - return this.normalize(type, payload); - }, - - /** - `extractArray` is used to deserialize an array of records - returned from the adapter. - - Example - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - extractArray: function(store, type, payload) { - return payload.map(function(json) { - return this.extractSingle(json); - }, this); - } - }); - ``` - - @method extractArray - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - @return {Array} array An array of deserialized objects - */ - extractArray: function(store, type, payload) { - return this.normalize(type, payload); - }, - - /** - `extractMeta` is used to deserialize any meta information in the - adapter payload. By default Ember Data expects meta information to - be located on the `meta` property of the payload object. - - Example - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - extractMeta: function(store, type, payload) { - if (payload && payload._pagination) { - store.metaForType(type, payload._pagination); - delete payload._pagination; - } - } - }); - ``` - - @method extractMeta - @param {DS.Store} store - @param {subclass of DS.Model} type - @param {Object} payload - */ - extractMeta: function(store, type, payload) { - if (payload && payload.meta) { - store.metaForType(type, payload.meta); - delete payload.meta; - } - }, - - /** - `keyForAttribute` can be used to define rules for how to convert an - attribute name in your model to a key in your JSON. - - Example - - ```javascript - App.ApplicationSerializer = DS.RESTSerializer.extend({ - keyForAttribute: function(attr) { - return Ember.String.underscore(attr).toUpperCase(); - } - }); - ``` - - @method keyForAttribute - @param {String} key - @return {String} normalized key - */ - - - /** - `keyForRelationship` can be used to define a custom key when - serializing relationship properties. By default `JSONSerializer` - does not provide an implementation of this method. - - Example - - ```javascript - App.PostSerializer = DS.JSONSerializer.extend({ - keyForRelationship: function(key, relationship) { - return 'rel_' + Ember.String.underscore(key); - } - }); - ``` - - @method keyForRelationship - @param {String} key - @param {String} relationship type - @return {String} normalized key - */ - - // HELPERS - - /** - @method transformFor - @private - @param {String} attributeType - @param {Boolean} skipAssertion - @return {DS.Transform} transform - */ - transformFor: function(attributeType, skipAssertion) { - var transform = this.container.lookup('transform:' + attributeType); - Ember.assert("Unable to find transform for '" + attributeType + "'", skipAssertion || !!transform); - return transform; - } -}); - -})(); - - - -(function() { -/** - @module ember-data -*/ -var get = Ember.get, capitalize = Ember.String.capitalize, underscore = Ember.String.underscore, DS = window.DS ; - -/** - Extend `Ember.DataAdapter` with ED specific code. - - @class DebugAdapter - @namespace DS - @extends Ember.DataAdapter - @private -*/ -DS.DebugAdapter = Ember.DataAdapter.extend({ - getFilters: function() { - return [ - { name: 'isNew', desc: 'New' }, - { name: 'isModified', desc: 'Modified' }, - { name: 'isClean', desc: 'Clean' } - ]; - }, - - detect: function(klass) { - return klass !== DS.Model && DS.Model.detect(klass); - }, - - columnsForType: function(type) { - var columns = [{ name: 'id', desc: 'Id' }], count = 0, self = this; - get(type, 'attributes').forEach(function(name, meta) { - if (count++ > self.attributeLimit) { return false; } - var desc = capitalize(underscore(name).replace('_', ' ')); - columns.push({ name: name, desc: desc }); - }); - return columns; - }, - - getRecords: function(type) { - return this.get('store').all(type); - }, - - getRecordColumnValues: function(record) { - var self = this, count = 0, - columnValues = { id: get(record, 'id') }; - - record.eachAttribute(function(key) { - if (count++ > self.attributeLimit) { - return false; - } - var value = get(record, key); - columnValues[key] = value; - }); - return columnValues; - }, - - getRecordKeywords: function(record) { - var keywords = [], keys = Ember.A(['id']); - record.eachAttribute(function(key) { - keys.push(key); - }); - keys.forEach(function(key) { - keywords.push(get(record, key)); - }); - return keywords; - }, - - getRecordFilterValues: function(record) { - return { - isNew: record.get('isNew'), - isModified: record.get('isDirty') && !record.get('isNew'), - isClean: !record.get('isDirty') - }; - }, - - getRecordColor: function(record) { - var color = 'black'; - if (record.get('isNew')) { - color = 'green'; - } else if (record.get('isDirty')) { - color = 'blue'; - } - return color; - }, - - observeRecord: function(record, recordUpdated) { - var releaseMethods = Ember.A(), self = this, - keysToObserve = Ember.A(['id', 'isNew', 'isDirty']); - - record.eachAttribute(function(key) { - keysToObserve.push(key); - }); - - keysToObserve.forEach(function(key) { - var handler = function() { - recordUpdated(self.wrapRecord(record)); - }; - Ember.addObserver(record, key, handler); - releaseMethods.push(function() { - Ember.removeObserver(record, key, handler); - }); - }); - - var release = function() { - releaseMethods.forEach(function(fn) { fn(); } ); - }; - - return release; - } - -}); - -})(); - - - -(function() { -/** - The `DS.Transform` class is used to serialize and deserialize model - attributes when they are saved or loaded from an - adapter. Subclassing `DS.Transform` is useful for creating custom - attributes. All subclasses of `DS.Transform` must implement a - `serialize` and a `deserialize` method. - - Example - - ```javascript - App.RawTransform = DS.Transform.extend({ - deserialize: function(serialized) { - return serialized; - }, - serialize: function(deserialized) { - return deserialized; - } - }); - ``` - - Usage - - ```javascript - var attr = DS.attr; - App.Requirement = DS.Model.extend({ - name: attr('string'), - optionsArray: attr('raw') - }); - ``` - - @class Transform - @namespace DS - */ -DS.Transform = Ember.Object.extend({ - /** - When given a deserialized value from a record attribute this - method must return the serialized value. - - Example - - ```javascript - serialize: function(deserialized) { - return Ember.isEmpty(deserialized) ? null : Number(deserialized); - } - ``` - - @method serialize - @param deserialized The deserialized value - @return The serialized value - */ - serialize: Ember.required(), - - /** - When given a serialize value from a JSON object this method must - return the deserialized value for the record attribute. - - Example - - ```javascript - deserialize: function(serialized) { - return empty(serialized) ? null : Number(serialized); - } - ``` - - @method deserialize - @param serialized The serialized value - @return The deserialized value - */ - deserialize: Ember.required() - -}); - -})(); - - - -(function() { - -/** - The `DS.BooleanTransform` class is used to serialize and deserialize - boolean attributes on Ember Data record objects. This transform is - used when `boolean` is passed as the type parameter to the - [DS.attr](../../data#method_attr) function. - - Usage - - ```javascript - var attr = DS.attr; - App.User = DS.Model.extend({ - isAdmin: attr('boolean'), - name: attr('string'), - email: attr('string') - }); - ``` - - @class BooleanTransform - @extends DS.Transform - @namespace DS - */ -DS.BooleanTransform = DS.Transform.extend({ - deserialize: function(serialized) { - var type = typeof serialized; - - if (type === "boolean") { - return serialized; - } else if (type === "string") { - return serialized.match(/^true$|^t$|^1$/i) !== null; - } else if (type === "number") { - return serialized === 1; - } else { - return false; - } - }, - - serialize: function(deserialized) { - return Boolean(deserialized); - } -}); - -})(); - - - -(function() { -/** - The `DS.DateTransform` class is used to serialize and deserialize - date attributes on Ember Data record objects. This transform is used - when `date` is passed as the type parameter to the - [DS.attr](../../data#method_attr) function. - - ```javascript - var attr = DS.attr; - App.Score = DS.Model.extend({ - value: attr('number'), - player: DS.belongsTo('player'), - date: attr('date') - }); - ``` - - @class DateTransform - @extends DS.Transform - @namespace DS - */ -DS.DateTransform = DS.Transform.extend({ - - deserialize: function(serialized) { - var type = typeof serialized; - - if (type === "string") { - return new Date(Ember.Date.parse(serialized)); - } else if (type === "number") { - return new Date(serialized); - } else if (serialized === null || serialized === undefined) { - // if the value is not present in the data, - // return undefined, not null. - return serialized; - } else { - return null; - } - }, - - serialize: function(date) { - if (date instanceof Date) { - // Serialize it as a number to maintain millisecond precision - return Number(date); - } else { - return null; - } - } - -}); - -})(); - - - -(function() { -var empty = Ember.isEmpty; -/** - The `DS.NumberTransform` class is used to serialize and deserialize - numeric attributes on Ember Data record objects. This transform is - used when `number` is passed as the type parameter to the - [DS.attr](../../data#method_attr) function. - - Usage - - ```javascript - var attr = DS.attr; - App.Score = DS.Model.extend({ - value: attr('number'), - player: DS.belongsTo('player'), - date: attr('date') - }); - ``` - - @class NumberTransform - @extends DS.Transform - @namespace DS - */ -DS.NumberTransform = DS.Transform.extend({ - - deserialize: function(serialized) { - return empty(serialized) ? null : Number(serialized); - }, - - serialize: function(deserialized) { - return empty(deserialized) ? null : Number(deserialized); - } -}); - -})(); - - - -(function() { -var none = Ember.isNone; - -/** - The `DS.StringTransform` class is used to serialize and deserialize - string attributes on Ember Data record objects. This transform is - used when `string` is passed as the type parameter to the - [DS.attr](../../data#method_attr) function. - - Usage - - ```javascript - var attr = DS.attr; - App.User = DS.Model.extend({ - isAdmin: attr('boolean'), - name: attr('string'), - email: attr('string') - }); - ``` - - @class StringTransform - @extends DS.Transform - @namespace DS - */ -DS.StringTransform = DS.Transform.extend({ - - deserialize: function(serialized) { - return none(serialized) ? null : String(serialized); - }, - - serialize: function(deserialized) { - return none(deserialized) ? null : String(deserialized); - } - -}); - -})(); - - - -(function() { - -})(); - - - -(function() { -/** - @module ember-data -*/ - -var set = Ember.set; - -/* - This code registers an injection for Ember.Application. - - If an Ember.js developer defines a subclass of DS.Store on their application, - this code will automatically instantiate it and make it available on the - router. - - Additionally, after an application's controllers have been injected, they will - each have the store made available to them. - - For example, imagine an Ember.js application with the following classes: - - App.Store = DS.Store.extend({ - adapter: 'custom' - }); - - App.PostsController = Ember.ArrayController.extend({ - // ... - }); - - When the application is initialized, `App.Store` will automatically be - instantiated, and the instance of `App.PostsController` will have its `store` - property set to that instance. - - Note that this code will only be run if the `ember-application` package is - loaded. If Ember Data is being used in an environment other than a - typical application (e.g., node.js where only `ember-runtime` is available), - this code will be ignored. -*/ - -Ember.onLoad('Ember.Application', function(Application) { - Application.initializer({ - name: "store", - - initialize: function(container, application) { - application.register('store:main', application.Store || DS.Store); - - // allow older names to be looked up - - var proxy = new DS.ContainerProxy(container); - proxy.registerDeprecations([ - {deprecated: 'serializer:_default', valid: 'serializer:-default'}, - {deprecated: 'serializer:_rest', valid: 'serializer:-rest'}, - {deprecated: 'adapter:_rest', valid: 'adapter:-rest'} - ]); - - // new go forward paths - application.register('serializer:-default', DS.JSONSerializer); - application.register('serializer:-rest', DS.RESTSerializer); - application.register('adapter:-rest', DS.RESTAdapter); - - // Eagerly generate the store so defaultStore is populated. - // TODO: Do this in a finisher hook - container.lookup('store:main'); - } - }); - - Application.initializer({ - name: "transforms", - before: "store", - - initialize: function(container, application) { - application.register('transform:boolean', DS.BooleanTransform); - application.register('transform:date', DS.DateTransform); - application.register('transform:number', DS.NumberTransform); - application.register('transform:string', DS.StringTransform); - } - }); - - Application.initializer({ - name: "data-adapter", - before: "store", - - initialize: function(container, application) { - application.register('data-adapter:main', DS.DebugAdapter); - } - }); - - Application.initializer({ - name: "injectStore", - before: "store", - - initialize: function(container, application) { - application.inject('controller', 'store', 'store:main'); - application.inject('route', 'store', 'store:main'); - application.inject('serializer', 'store', 'store:main'); - application.inject('data-adapter', 'store', 'store:main'); - } - }); - -}); - -})(); - - - -(function() { -/** - @module ember-data -*/ - -/** - Date.parse with progressive enhancement for ISO 8601 <https://github.com/csnover/js-iso8601> - - © 2011 Colin Snover <http://zetafleet.com> - - Released under MIT license. - - @class Date - @namespace Ember - @static -*/ -Ember.Date = Ember.Date || {}; - -var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ]; - -/** - @method parse - @param date -*/ -Ember.Date.parse = function (date) { - var timestamp, struct, minutesOffset = 0; - - // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string - // before falling back to any implementation-specific date parsing, so thatâs what we do, even if native - // implementations could be faster - // 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm - 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))) { - // avoid NaN timestamps caused by âundefinedâ values being passed to Date.UTC - for (var i = 0, k; (k = numericKeys[i]); ++i) { - struct[k] = +struct[k] || 0; - } - - // allow undefined days and months - struct[2] = (+struct[2] || 1) - 1; - struct[3] = +struct[3] || 1; - - if (struct[8] !== 'Z' && struct[9] !== undefined) { - minutesOffset = struct[10] * 60 + struct[11]; - - if (struct[9] === '+') { - minutesOffset = 0 - minutesOffset; - } - } - - timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]); - } - else { - timestamp = origParse ? origParse(date) : NaN; - } - - return timestamp; -}; - -if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) { - Date.parse = Ember.Date.parse; -} - -})(); - - - -(function() { - -})(); - - - -(function() { -/** - @module ember-data -*/ - -var get = Ember.get, set = Ember.set; - -/** - A record array is an array that contains records of a certain type. The record - array materializes records as needed when they are retrieved for the first - time. You should not create record arrays yourself. Instead, an instance of - `DS.RecordArray` or its subclasses will be returned by your application's store - in response to queries. - - @class RecordArray - @namespace DS - @extends Ember.ArrayProxy - @uses Ember.Evented -*/ - -DS.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, { - /** - The model type contained by this record array. - - @property type - @type DS.Model - */ - type: null, - - /** - The array of client ids backing the record array. When a - record is requested from the record array, the record - for the client id at the same index is materialized, if - necessary, by the store. - - @property content - @private - @type Ember.Array - */ - content: null, - - /** - The flag to signal a `RecordArray` is currently loading data. - - Example - - ```javascript - var people = store.all(App.Person); - people.get('isLoaded'); // true - ``` - - @property isLoaded - @type Boolean - */ - isLoaded: false, - /** - The flag to signal a `RecordArray` is currently loading data. - - Example - - ```javascript - var people = store.all(App.Person); - people.get('isUpdating'); // false - people.update(); - people.get('isUpdating'); // true - ``` - - @property isUpdating - @type Boolean - */ - isUpdating: false, - - /** - The store that created this record array. - - @property store - @private - @type DS.Store - */ - store: null, - - /** - Retrieves an object from the content by index. - - @method objectAtContent - @private - @param {Number} index - @return {DS.Model} record - */ - objectAtContent: function(index) { - var content = get(this, 'content'); - - return content.objectAt(index); - }, - - /** - Used to get the latest version of all of the records in this array - from the adapter. - - Example - - ```javascript - var people = store.all(App.Person); - people.get('isUpdating'); // false - people.update(); - people.get('isUpdating'); // true - ``` - - @method update - */ - update: function() { - if (get(this, 'isUpdating')) { return; } - - var store = get(this, 'store'), - type = get(this, 'type'); - - return store.fetchAll(type, this); - }, - - /** - Adds a record to the `RecordArray`. - - @method addRecord - @private - @param {DS.Model} record - */ - addRecord: function(record) { - get(this, 'content').addObject(record); - }, - - /** - Removes a record to the `RecordArray`. - - @method removeRecord - @private - @param {DS.Model} record - */ - removeRecord: function(record) { - get(this, 'content').removeObject(record); - }, - - /** - Saves all of the records in the `RecordArray`. - - Example - - ```javascript - var messages = store.all(App.Message); - messages.forEach(function(message) { - message.set('hasBeenSeen', true); - }); - messages.save(); - ``` - - @method save - @return {DS.PromiseArray} promise - */ - save: function() { - var promiseLabel = "DS: RecordArray#save " + get(this, 'type'); - var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) { - return Ember.A(array); - }, null, "DS: RecordArray#save apply Ember.NativeArray"); - - return DS.PromiseArray.create({ promise: promise }); - } -}); - -})(); - - - -(function() { -/** - @module ember-data -*/ - -var get = Ember.get; - -/** - Represents a list of records whose membership is determined by the - store. As records are created, loaded, or modified, the store - evaluates them to determine if they should be part of the record - array. - - @class FilteredRecordArray - @namespace DS - @extends DS.RecordArray -*/ -DS.FilteredRecordArray = DS.RecordArray.extend({ - /** - The filterFunction is a function used to test records from the store to - determine if they should be part of the record array. - - Example - - ```javascript - var allPeople = store.all('person'); - allPeople.mapBy('name'); // ["Tom Dale", "Yehuda Katz", "Trek Glowacki"] - - var people = store.filter('person', function(person) { - if (person.get('name').match(/Katz$/)) { return true; } - }); - people.mapBy('name'); // ["Yehuda Katz"] - - var notKatzFilter = function(person) { - return !person.get('name').match(/Katz$/); - }; - people.set('filterFunction', notKatzFilter); - people.mapBy('name'); // ["Tom Dale", "Trek Glowacki"] - ``` - - @method filterFunction - @param {DS.Model} record - @return {Boolean} `true` if the record should be in the array - */ - filterFunction: null, - isLoaded: true, - - replace: function() { - var type = get(this, 'type').toString(); - throw new Error("The result of a client-side filter (on " + type + ") is immutable."); - }, - - /** - @method updateFilter - @private - */ - updateFilter: Ember.observer(function() { - var manager = get(this, 'manager'); - manager.updateFilter(this, get(this, 'type'), get(this, 'filterFunction')); - }, 'filterFunction') -}); - -})(); - - - -(function() { -/** - @module ember-data -*/ - -var get = Ember.get, set = Ember.set; - -/** - Represents an ordered list of records whose order and membership is - determined by the adapter. For example, a query sent to the adapter - may trigger a search on the server, whose results would be loaded - into an instance of the `AdapterPopulatedRecordArray`. - - @class AdapterPopulatedRecordArray - @namespace DS - @extends DS.RecordArray -*/ -DS.AdapterPopulatedRecordArray = DS.RecordArray.extend({ - query: null, - - replace: function() { - var type = get(this, 'type').toString(); - throw new Error("The result of a server query (on " + type + ") is immutable."); - }, - - /** - @method load - @private - @param {Array} data - */ - load: function(data) { - var store = get(this, 'store'), - type = get(this, 'type'), - records = store.pushMany(type, data), - meta = store.metadataFor(type); - - this.setProperties({ - content: Ember.A(records), - isLoaded: true, - meta: meta - }); - - // TODO: does triggering didLoad event should be the last action of the runLoop? - Ember.run.once(this, 'trigger', 'didLoad'); - } -}); - -})(); - - - -(function() { -/** - @module ember-data -*/ - -var get = Ember.get, set = Ember.set; -var map = Ember.EnumerableUtils.map; - -/** - A `ManyArray` is a `RecordArray` that represents the contents of a has-many - relationship. - - The `ManyArray` is instantiated lazily the first time the relationship is - requested. - - ### Inverses - - Often, the relationships in Ember Data applications will have - an inverse. For example, imagine the following models are - defined: - - ```javascript - App.Post = DS.Model.extend({ - comments: DS.hasMany('comment') - }); - - App.Comment = DS.Model.extend({ - post: DS.belongsTo('post') - }); - ``` - - If you created a new instance of `App.Post` and added - a `App.Comment` record to its `comments` has-many - relationship, you would expect the comment's `post` - property to be set to the post that contained - the has-many. - - We call the record to which a relationship belongs the - relationship's _owner_. - - @class ManyArray - @namespace DS - @extends DS.RecordArray -*/ -DS.ManyArray = DS.RecordArray.extend({ - init: function() { - this._super.apply(this, arguments); - this._changesToSync = Ember.OrderedSet.create(); - }, - - /** - The property name of the relationship - - @property {String} name - @private - */ - name: null, - - /** - The record to which this relationship belongs. - - @property {DS.Model} owner - @private - */ - owner: null, - - /** - `true` if the relationship is polymorphic, `false` otherwise. - - @property {Boolean} isPolymorphic - @private - */ - isPolymorphic: false, - - // LOADING STATE - - isLoaded: false, - - /** - Used for async `hasMany` arrays - to keep track of when they will resolve. - - @property {Ember.RSVP.Promise} promise - @private - */ - promise: null, - - /** - @method loadingRecordsCount - @param {Number} count - @private - */ - loadingRecordsCount: function(count) { - this.loadingRecordsCount = count; - }, - - /** - @method loadedRecord - @private - */ - loadedRecord: function() { - this.loadingRecordsCount--; - if (this.loadingRecordsCount === 0) { - set(this, 'isLoaded', true); - this.trigger('didLoad'); - } - }, - - /** - @method fetch - @private - */ - fetch: function() { - var records = get(this, 'content'), - store = get(this, 'store'), - owner = get(this, 'owner'), - resolver = Ember.RSVP.defer("DS: ManyArray#fetch " + get(this, 'type')); - - var unloadedRecords = records.filterProperty('isEmpty', true); - store.fetchMany(unloadedRecords, owner, resolver); - }, - - // Overrides Ember.Array's replace method to implement - replaceContent: function(index, removed, added) { - // Map the array of record objects into an array of client ids. - added = map(added, function(record) { - Ember.assert("You cannot add '" + record.constructor.typeKey + "' records to this relationship (only '" + this.type.typeKey + "' allowed)", !this.type || record instanceof this.type); - return record; - }, this); - - this._super(index, removed, added); - }, - - arrangedContentDidChange: function() { - Ember.run.once(this, 'fetch'); - }, - - arrayContentWillChange: function(index, removed, added) { - var owner = get(this, 'owner'), - name = get(this, 'name'); - - if (!owner._suspendedRelationships) { - // This code is the first half of code that continues inside - // of arrayContentDidChange. It gets or creates a change from - // the child object, adds the current owner as the old - // parent if this is the first time the object was removed - // from a ManyArray, and sets `newParent` to null. - // - // Later, if the object is added to another ManyArray, - // the `arrayContentDidChange` will set `newParent` on - // the change. - for (var i=index; i<index+removed; i++) { - var record = get(this, 'content').objectAt(i); - - var change = DS.RelationshipChange.createChange(owner, record, get(this, 'store'), { - parentType: owner.constructor, - changeType: "remove", - kind: "hasMany", - key: name - }); - - this._changesToSync.add(change); - } - } - - return this._super.apply(this, arguments); - }, - - arrayContentDidChange: function(index, removed, added) { - this._super.apply(this, arguments); - - var owner = get(this, 'owner'), - name = get(this, 'name'), - store = get(this, 'store'); - - if (!owner._suspendedRelationships) { - // This code is the second half of code that started in - // `arrayContentWillChange`. It gets or creates a change - // from the child object, and adds the current owner as - // the new parent. - for (var i=index; i<index+added; i++) { - var record = get(this, 'content').objectAt(i); - - var change = DS.RelationshipChange.createChange(owner, record, store, { - parentType: owner.constructor, - changeType: "add", - kind:"hasMany", - key: name - }); - change.hasManyName = name; - - this._changesToSync.add(change); - } - - // We wait until the array has finished being - // mutated before syncing the OneToManyChanges created - // in arrayContentWillChange, so that the array - // membership test in the sync() logic operates - // on the final results. - this._changesToSync.forEach(function(change) { - change.sync(); - }); - - this._changesToSync.clear(); - } - }, - - /** - Create a child record within the owner - - @method createRecord - @private - @param {Object} hash - @return {DS.Model} record - */ - createRecord: function(hash) { - var owner = get(this, 'owner'), - store = get(owner, 'store'), - type = get(this, 'type'), - record; - - Ember.assert("You cannot add '" + type.typeKey + "' records to this polymorphic relationship.", !get(this, 'isPolymorphic')); - - record = store.createRecord.call(store, type, hash); - this.pushObject(record); - - return record; - } - -}); - -})(); - - - -(function() { -/** - @module ember-data -*/ - -})(); - - - -(function() { -/*globals Ember*/ -/*jshint eqnull:true*/ -/** - @module ember-data -*/ - -var get = Ember.get, set = Ember.set; -var once = Ember.run.once; -var isNone = Ember.isNone; -var forEach = Ember.EnumerableUtils.forEach; -var indexOf = Ember.EnumerableUtils.indexOf; -var map = Ember.EnumerableUtils.map; -var resolve = Ember.RSVP.resolve; -var copy = Ember.copy; - -// Implementors Note: -// -// The variables in this file are consistently named according to the following -// scheme: -// -// * +id+ means an identifier managed by an external source, provided inside -// the data provided by that source. These are always coerced to be strings -// before being used internally. -// * +clientId+ means a transient numerical identifier generated at runtime by -// the data store. It is important primarily because newly created objects may -// not yet have an externally generated id. -// * +reference+ means a record reference object, which holds metadata about a -// record, even if it has not yet been fully materialized. -// * +type+ means a subclass of DS.Model. - -// Used by the store to normalize IDs entering the store. Despite the fact -// that developers may provide IDs as numbers (e.g., `store.find(Person, 1)`), -// it is important that internally we use strings, since IDs may be serialized -// and lose type information. For example, Ember's router may put a record's -// ID into the URL, and if we later try to deserialize that URL and find the -// corresponding record, we will not know if it is a string or a number. -var coerceId = function(id) { - return id == null ? null : id+''; -}; - -/** - The store contains all of the data for records loaded from the server. - It is also responsible for creating instances of `DS.Model` that wrap - the individual data for a record, so that they can be bound to in your - Handlebars templates. - - Define your application's store like this: - - ```javascript - MyApp.Store = DS.Store.extend(); - ``` - - Most Ember.js applications will only have a single `DS.Store` that is - automatically created by their `Ember.Application`. - - You can retrieve models from the store in several ways. To retrieve a record - for a specific id, use `DS.Store`'s `find()` method: - - ```javascript - var person = store.find('person', 123); - ``` - - If your application has multiple `DS.Store` instances (an unusual case), you can - specify which store should be used: - - ```javascript - var person = store.find(App.Person, 123); - ``` - - By default, the store will talk to your backend using a standard - REST mechanism. You can customize how the store talks to your - backend by specifying a custom adapter: - - ```javascript - MyApp.store = DS.Store.create({ - adapter: 'MyApp.CustomAdapter' - }); - ``` - - You can learn more about writing a custom adapter by reading the `DS.Adapter` - documentation. - - @class Store - @namespace DS - @extends Ember.Object -*/ -DS.Store = Ember.Object.extend({ - - /** - @method init - @private - */ - init: function() { - // internal bookkeeping; not observable - this.typeMaps = {}; - this.recordArrayManager = DS.RecordArrayManager.create({ - store: this - }); - this._relationshipChanges = {}; - this._pendingSave = []; - }, - - /** - The adapter to use to communicate to a backend server or other persistence layer. - - This can be specified as an instance, class, or string. - - If you want to specify `App.CustomAdapter` as a string, do: - - ```js - adapter: 'custom' - ``` - - @property adapter - @default DS.RESTAdapter - @type {DS.Adapter|String} - */ - adapter: '-rest', - - /** - Returns a JSON representation of the record using a custom - type-specific serializer, if one exists. - - The available options are: - - * `includeId`: `true` if the record's ID should be included in - the JSON representation - - @method serialize - @private - @param {DS.Model} record the record to serialize - @param {Object} options an options hash - */ - serialize: function(record, options) { - return this.serializerFor(record.constructor.typeKey).serialize(record, options); - }, - - /** - This property returns the adapter, after resolving a possible - string key. - - If the supplied `adapter` was a class, or a String property - path resolved to a class, this property will instantiate the - class. - - This property is cacheable, so the same instance of a specified - adapter class should be used for the lifetime of the store. - - @property defaultAdapter - @private - @returns DS.Adapter - */ - defaultAdapter: Ember.computed('adapter', function() { - var adapter = get(this, 'adapter'); - - Ember.assert('You tried to set `adapter` property to an instance of `DS.Adapter`, where it should be a name or a factory', !(adapter instanceof DS.Adapter)); - - if (typeof adapter === 'string') { - adapter = this.container.lookup('adapter:' + adapter) || this.container.lookup('adapter:application') || this.container.lookup('adapter:-rest'); - } - - if (DS.Adapter.detect(adapter)) { - adapter = adapter.create({ container: this.container }); - } - - return adapter; - }), - - // ..................... - // . CREATE NEW RECORD . - // ..................... - - /** - Create a new record in the current store. The properties passed - to this method are set on the newly created record. - - To create a new instance of `App.Post`: - - ```js - store.createRecord('post', { - title: "Rails is omakase" - }); - ``` - - @method createRecord - @param {String} type - @param {Object} properties a hash of properties to set on the - newly created record. - @returns {DS.Model} record - */ - createRecord: function(type, properties) { - type = this.modelFor(type); - - properties = copy(properties) || {}; - - // If the passed properties do not include a primary key, - // give the adapter an opportunity to generate one. Typically, - // client-side ID generators will use something like uuid.js - // to avoid conflicts. - - if (isNone(properties.id)) { - properties.id = this._generateId(type); - } - - // Coerce ID to a string - properties.id = coerceId(properties.id); - - var record = this.buildRecord(type, properties.id); - - // Move the record out of its initial `empty` state into - // the `loaded` state. - record.loadedData(); - - // Set the properties specified on the record. - record.setProperties(properties); - - return record; - }, - - /** - If possible, this method asks the adapter to generate an ID for - a newly created record. - - @method _generateId - @private - @param {String} type - @returns {String} if the adapter can generate one, an ID - */ - _generateId: function(type) { - var adapter = this.adapterFor(type); - - if (adapter && adapter.generateIdForRecord) { - return adapter.generateIdForRecord(this); - } - - return null; - }, - - // ................. - // . DELETE RECORD . - // ................. - - /** - For symmetry, a record can be deleted via the store. - - Example - - ```javascript - var post = store.createRecord('post', { - title: "Rails is omakase" - }); - - store.deleteRecord(post); - ``` - - @method deleteRecord - @param {DS.Model} record - */ - deleteRecord: function(record) { - record.deleteRecord(); - }, - - /** - For symmetry, a record can be unloaded via the store. Only - non-dirty records can be unloaded. - - Example - - ```javascript - store.find('post', 1).then(function(post) { - store.unloadRecord(post); - }); - ``` - - @method unloadRecord - @param {DS.Model} record - */ - unloadRecord: function(record) { - record.unloadRecord(); - }, - - // ................ - // . FIND RECORDS . - // ................ - - /** - This is the main entry point into finding records. The first parameter to - this method is the model's name as a string. - - --- - - To find a record by ID, pass the `id` as the second parameter: - - ```javascript - store.find('person', 1); - ``` - - The `find` method will always return a **promise** that will be resolved - with the record. If the record was already in the store, the promise will - be resolved immediately. Otherwise, the store will ask the adapter's `find` - method to find the necessary data. - - The `find` method will always resolve its promise with the same object for - a given type and `id`. - - --- - - To find all records for a type, call `find` with no additional parameters: - - ```javascript - store.find('person'); - ``` - - This will ask the adapter's `findAll` method to find the records for the - given type, and return a promise that will be resolved once the server - returns the values. - - --- - - To find a record by a query, call `find` with a hash as the second - parameter: - - ```javascript - store.find(App.Person, { page: 1 }); - ``` - - This will ask the adapter's `findQuery` method to find the records for - the query, and return a promise that will be resolved once the server - responds. - - @method find - @param {String or subclass of DS.Model} type - @param {Object|String|Integer|null} id - @return {Promise} promise - */ - find: function(type, id) { - if (id === undefined) { - return this.findAll(type); - } - - // We are passed a query instead of an id. - if (Ember.typeOf(id) === 'object') { - return this.findQuery(type, id); - } - - return this.findById(type, coerceId(id)); - }, - - /** - This method returns a record for a given type and id combination. - - @method findById - @private - @param {String or subclass of DS.Model} type - @param {String|Integer} id - @return {Promise} promise - */ - findById: function(type, id) { - type = this.modelFor(type); - - var record = this.recordForId(type, id); - - var promise = this.fetchRecord(record) || resolve(record, "DS: Store#findById " + type + " with id: " + id); - return promiseObject(promise); - }, - - /** - This method makes a series of requests to the adapter's `find` method - and returns a promise that resolves once they are all loaded. - - @private - @method findByIds - @param {String} type - @param {Array} ids - @returns {Promise} promise - */ - findByIds: function(type, ids) { - var store = this; - var promiseLabel = "DS: Store#findByIds " + type; - return promiseArray(Ember.RSVP.all(map(ids, function(id) { - return store.findById(type, id); - })).then(Ember.A, null, "DS: Store#findByIds of " + type + " complete")); - }, - - /** - This method is called by `findById` if it discovers that a particular - type/id pair hasn't been loaded yet to kick off a request to the - adapter. - - @method fetchRecord - @private - @param {DS.Model} record - @returns {Promise} promise - */ - fetchRecord: function(record) { - if (isNone(record)) { return null; } - if (record._loadingPromise) { return record._loadingPromise; } - if (!get(record, 'isEmpty')) { return null; } - - var type = record.constructor, - id = get(record, 'id'); - - var adapter = this.adapterFor(type); - - Ember.assert("You tried to find a record but you have no adapter (for " + type + ")", adapter); - Ember.assert("You tried to find a record but your adapter (for " + type + ") does not implement 'find'", adapter.find); - - var promise = _find(adapter, this, type, id); - record.loadingData(promise); - return promise; - }, - - /** - Get a record by a given type and ID without triggering a fetch. - - This method will synchronously return the record if it's available. - Otherwise, it will return null. - - ```js - var post = store.getById('post', 1); - ``` - - @method getById - @param {String or subclass of DS.Model} type - @param {String|Integer} id - @param {DS.Model} record - */ - getById: function(type, id) { - if (this.hasRecordForId(type, id)) { - return this.recordForId(type, id); - } else { - return null; - } - }, - - /** - This method is called by the record's `reload` method. - - This method calls the adapter's `find` method, which returns a promise. When - **that** promise resolves, `reloadRecord` will resolve the promise returned - by the record's `reload`. - - @method reloadRecord - @private - @param {DS.Model} record - @return {Promise} promise - */ - reloadRecord: function(record) { - var type = record.constructor, - adapter = this.adapterFor(type), - id = get(record, 'id'); - - Ember.assert("You cannot reload a record without an ID", id); - Ember.assert("You tried to reload a record but you have no adapter (for " + type + ")", adapter); - Ember.assert("You tried to reload a record but your adapter does not implement `find`", adapter.find); - - return _find(adapter, this, type, id); - }, - - /** - This method takes a list of records, groups the records by type, - converts the records into IDs, and then invokes the adapter's `findMany` - method. - - The records are grouped by type to invoke `findMany` on adapters - for each unique type in records. - - It is used both by a brand new relationship (via the `findMany` - method) or when the data underlying an existing relationship - changes. - - @method fetchMany - @private - @param {Array} records - @param {DS.Model} owner - @param {Resolver} resolver - */ - fetchMany: function(records, owner, resolver) { - if (!records.length) { return; } - - // Group By Type - var recordsByTypeMap = Ember.MapWithDefault.create({ - defaultValue: function() { return Ember.A(); } - }); - - forEach(records, function(record) { - recordsByTypeMap.get(record.constructor).push(record); - }); - - forEach(recordsByTypeMap, function(type, records) { - var ids = records.mapProperty('id'), - adapter = this.adapterFor(type); - - Ember.assert("You tried to load many records but you have no adapter (for " + type + ")", adapter); - Ember.assert("You tried to load many records but your adapter does not implement `findMany`", adapter.findMany); - - resolver.resolve(_findMany(adapter, this, type, ids, owner)); - }, this); - }, - - /** - Returns true if a record for a given type and ID is already loaded. - - @method hasRecordForId - @param {String or subclass of DS.Model} type - @param {String|Integer} id - @returns {Boolean} - */ - hasRecordForId: function(type, id) { - id = coerceId(id); - type = this.modelFor(type); - return !!this.typeMapFor(type).idToRecord[id]; - }, - - /** - Returns id record for a given type and ID. If one isn't already loaded, - it builds a new record and leaves it in the `empty` state. - - @method recordForId - @private - @param {String or subclass of DS.Model} type - @param {String|Integer} id - @returns {DS.Model} record - */ - recordForId: function(type, id) { - type = this.modelFor(type); - - id = coerceId(id); - - var record = this.typeMapFor(type).idToRecord[id]; - - if (!record) { - record = this.buildRecord(type, id); - } - - return record; - }, - - /** - @method findMany - @private - @param {DS.Model} owner - @param {Array} records - @param {String or subclass of DS.Model} type - @param {Resolver} resolver - @return {DS.ManyArray} records - */ - findMany: function(owner, records, type, resolver) { - type = this.modelFor(type); - - records = Ember.A(records); - - var unloadedRecords = records.filterProperty('isEmpty', true), - manyArray = this.recordArrayManager.createManyArray(type, records); - - forEach(unloadedRecords, function(record) { - record.loadingData(); - }); - - manyArray.loadingRecordsCount = unloadedRecords.length; - - if (unloadedRecords.length) { - forEach(unloadedRecords, function(record) { - this.recordArrayManager.registerWaitingRecordArray(record, manyArray); - }, this); - - this.fetchMany(unloadedRecords, owner, resolver); - } else { - if (resolver) { resolver.resolve(); } - manyArray.set('isLoaded', true); - Ember.run.once(manyArray, 'trigger', 'didLoad'); - } - - return manyArray; - }, - - /** - If a relationship was originally populated by the adapter as a link - (as opposed to a list of IDs), this method is called when the - relationship is fetched. - - The link (which is usually a URL) is passed through unchanged, so the - adapter can make whatever request it wants. - - The usual use-case is for the server to register a URL as a link, and - then use that URL in the future to make a request for the relationship. - - @method findHasMany - @private - @param {DS.Model} owner - @param {any} link - @param {String or subclass of DS.Model} type - @param {Resolver} resolver - @return {DS.ManyArray} - */ - findHasMany: function(owner, link, relationship, resolver) { - var adapter = this.adapterFor(owner.constructor); - - Ember.assert("You tried to load a hasMany relationship but you have no adapter (for " + owner.constructor + ")", adapter); - Ember.assert("You tried to load a hasMany relationship from a specified `link` in the original payload but your adapter does not implement `findHasMany`", adapter.findHasMany); - - var records = this.recordArrayManager.createManyArray(relationship.type, Ember.A([])); - resolver.resolve(_findHasMany(adapter, this, owner, link, relationship)); - return records; - }, - - /** - @method findBelongsTo - @private - @param {DS.Model} owner - @param {any} link - @param {Relationship} relationship - @param {Resolver} resolver - */ - findBelongsTo: function(owner, link, relationship, resolver) { - var adapter = this.adapterFor(owner.constructor); - - Ember.assert("You tried to load a belongsTo relationship but you have no adapter (for " + owner.constructor + ")", adapter); - Ember.assert("You tried to load a belongsTo relationship from a specified `link` in the original payload but your adapter does not implement `findBelongsTo`", adapter.findBelongsTo); - - resolver.resolve(_findBelongsTo(adapter, this, owner, link, relationship)); - }, - - /** - This method delegates a query to the adapter. This is the one place where - adapter-level semantics are exposed to the application. - - Exposing queries this way seems preferable to creating an abstract query - language for all server-side queries, and then require all adapters to - implement them. - - This method returns a promise, which is resolved with a `RecordArray` - once the server returns. - - @method findQuery - @private - @param {String or subclass of DS.Model} type - @param {any} query an opaque query to be used by the adapter - @return {Promise} promise - */ - findQuery: function(type, query) { - type = this.modelFor(type); - - var array = this.recordArrayManager - .createAdapterPopulatedRecordArray(type, query); - - var adapter = this.adapterFor(type), - promiseLabel = "DS: Store#findQuery " + type, - resolver = Ember.RSVP.defer(promiseLabel); - - Ember.assert("You tried to load a query but you have no adapter (for " + type + ")", adapter); - Ember.assert("You tried to load a query but your adapter does not implement `findQuery`", adapter.findQuery); - - resolver.resolve(_findQuery(adapter, this, type, query, array)); - - return promiseArray(resolver.promise); - }, - - /** - This method returns an array of all records adapter can find. - It triggers the adapter's `findAll` method to give it an opportunity to populate - the array with records of that type. - - @method findAll - @private - @param {String or subclass of DS.Model} type - @return {DS.AdapterPopulatedRecordArray} - */ - findAll: function(type) { - type = this.modelFor(type); - - return this.fetchAll(type, this.all(type)); - }, - - /** - @method fetchAll - @private - @param {DS.Model} type - @param {DS.RecordArray} array - @returns {Promise} promise - */ - fetchAll: function(type, array) { - var adapter = this.adapterFor(type), - sinceToken = this.typeMapFor(type).metadata.since; - - set(array, 'isUpdating', true); - - Ember.assert("You tried to load all records but you have no adapter (for " + type + ")", adapter); - Ember.assert("You tried to load all records but your adapter does not implement `findAll`", adapter.findAll); - - return promiseArray(_findAll(adapter, this, type, sinceToken)); - }, - - /** - @method didUpdateAll - @param {DS.Model} type - */ - didUpdateAll: function(type) { - var findAllCache = this.typeMapFor(type).findAllCache; - set(findAllCache, 'isUpdating', false); - }, - - /** - This method returns a filtered array that contains all of the known records - for a given type. - - Note that because it's just a filter, it will have any locally - created records of the type. - - Also note that multiple calls to `all` for a given type will always - return the same RecordArray. - - Example - - ```javascript - var local_posts = store.all(App.Post); - ``` - - @method all - @param {String or subclass of DS.Model} type - @return {DS.RecordArray} - */ - all: function(type) { - type = this.modelFor(type); - - var typeMap = this.typeMapFor(type), - findAllCache = typeMap.findAllCache; - - if (findAllCache) { return findAllCache; } - - var array = this.recordArrayManager.createRecordArray(type); - - typeMap.findAllCache = array; - return array; - }, - - - /** - This method unloads all of the known records for a given type. - - ```javascript - store.unloadAll(App.Post); - ``` - - @method unloadAll - @param {String or subclass of DS.Model} type - */ - unloadAll: function(type) { - type = this.modelFor(type); - - var typeMap = this.typeMapFor(type), - records = typeMap.records.splice(0), record; - - while(record = records.pop()) { - record.unloadRecord(); - } - - typeMap.findAllCache = null; - }, - - /** - Takes a type and filter function, and returns a live RecordArray that - remains up to date as new records are loaded into the store or created - locally. - - The callback function takes a materialized record, and returns true - if the record should be included in the filter and false if it should - not. - - The filter function is called once on all records for the type when - it is created, and then once on each newly loaded or created record. - - If any of a record's properties change, or if it changes state, the - filter function will be invoked again to determine whether it should - still be in the array. - - Optionally you can pass a query which will be triggered at first. The - results returned by the server could then appear in the filter if they - match the filter function. - - Example - - ```javascript - store.filter(App.Post, {unread: true}, function(post) { - return post.get('unread'); - }).then(function(unreadPosts) { - unreadPosts.get('length'); // 5 - var unreadPost = unreadPosts.objectAt(0); - unreadPost.set('unread', false); - unreadPosts.get('length'); // 4 - }); - ``` - - @method filter - @param {String or subclass of DS.Model} type - @param {Object} query optional query - @param {Function} filter - @return {DS.PromiseArray} - */ - filter: function(type, query, filter) { - var promise; - - // allow an optional server query - if (arguments.length === 3) { - promise = this.findQuery(type, query); - } else if (arguments.length === 2) { - filter = query; - } - - type = this.modelFor(type); - - var array = this.recordArrayManager - .createFilteredRecordArray(type, filter); - promise = promise || resolve(array); - - return promiseArray(promise.then(function() { - return array; - }, null, "DS: Store#filter of " + type)); - }, - - /** - This method returns if a certain record is already loaded - in the store. Use this function to know beforehand if a find() - will result in a request or that it will be a cache hit. - - Example - - ```javascript - store.recordIsLoaded(App.Post, 1); // false - store.find(App.Post, 1).then(function() { - store.recordIsLoaded(App.Post, 1); // true - }); - ``` - - @method recordIsLoaded - @param {String or subclass of DS.Model} type - @param {string} id - @return {boolean} - */ - recordIsLoaded: function(type, id) { - if (!this.hasRecordForId(type, id)) { return false; } - return !get(this.recordForId(type, id), 'isEmpty'); - }, - - /** - This method returns the metadata for a specific type. - - @method metadataFor - @param {String or subclass of DS.Model} type - @return {object} - */ - metadataFor: function(type) { - type = this.modelFor(type); - return this.typeMapFor(type).metadata; - }, - - // ............ - // . UPDATING . - // ............ - - /** - If the adapter updates attributes or acknowledges creation - or deletion, the record will notify the store to update its - membership in any filters. - To avoid thrashing, this method is invoked only once per - - run loop per record. - - @method dataWasUpdated - @private - @param {Class} type - @param {DS.Model} record - */ - dataWasUpdated: function(type, record) { - this.recordArrayManager.recordDidChange(record); - }, - - // .............. - // . PERSISTING . - // .............. - - /** - This method is called by `record.save`, and gets passed a - resolver for the promise that `record.save` returns. - - It schedules saving to happen at the end of the run loop. - - @method scheduleSave - @private - @param {DS.Model} record - @param {Resolver} resolver - */ - scheduleSave: function(record, resolver) { - record.adapterWillCommit(); - this._pendingSave.push([record, resolver]); - once(this, 'flushPendingSave'); - }, - - /** - This method is called at the end of the run loop, and - flushes any records passed into `scheduleSave` - - @method flushPendingSave - @private - */ - flushPendingSave: function() { - var pending = this._pendingSave.slice(); - this._pendingSave = []; - - forEach(pending, function(tuple) { - var record = tuple[0], resolver = tuple[1], - adapter = this.adapterFor(record.constructor), - operation; - - if (get(record, 'isNew')) { - operation = 'createRecord'; - } else if (get(record, 'isDeleted')) { - operation = 'deleteRecord'; - } else { - operation = 'updateRecord'; - } - - resolver.resolve(_commit(adapter, this, operation, record)); - }, this); - }, - - /** - This method is called once the promise returned by an - adapter's `createRecord`, `updateRecord` or `deleteRecord` - is resolved. - - If the data provides a server-generated ID, it will - update the record and the store's indexes. - - @method didSaveRecord - @private - @param {DS.Model} record the in-flight record - @param {Object} data optional data (see above) - */ - didSaveRecord: function(record, data) { - if (data) { - // normalize relationship IDs into records - data = normalizeRelationships(this, record.constructor, data, record); - - this.updateId(record, data); - } - - record.adapterDidCommit(data); - }, - - /** - This method is called once the promise returned by an - adapter's `createRecord`, `updateRecord` or `deleteRecord` - is rejected with a `DS.InvalidError`. - - @method recordWasInvalid - @private - @param {DS.Model} record - @param {Object} errors - */ - recordWasInvalid: function(record, errors) { - record.adapterDidInvalidate(errors); - }, - - /** - This method is called once the promise returned by an - adapter's `createRecord`, `updateRecord` or `deleteRecord` - is rejected (with anything other than a `DS.InvalidError`). - - @method recordWasError - @private - @param {DS.Model} record - */ - recordWasError: function(record) { - record.adapterDidError(); - }, - - /** - When an adapter's `createRecord`, `updateRecord` or `deleteRecord` - resolves with data, this method extracts the ID from the supplied - data. - - @method updateId - @private - @param {DS.Model} record - @param {Object} data - */ - updateId: function(record, data) { - var oldId = get(record, 'id'), - id = coerceId(data.id); - - Ember.assert("An adapter cannot assign a new id to a record that already has an id. " + record + " had id: " + oldId + " and you tried to update it with " + id + ". This likely happened because your server returned data in response to a find or update that had a different id than the one you sent.", oldId === null || id === oldId); - - this.typeMapFor(record.constructor).idToRecord[id] = record; - - set(record, 'id', id); - }, - - /** - Returns a map of IDs to client IDs for a given type. - - @method typeMapFor - @private - @param type - @return {Object} typeMap - */ - typeMapFor: function(type) { - var typeMaps = get(this, 'typeMaps'), - guid = Ember.guidFor(type), - typeMap; - - typeMap = typeMaps[guid]; - - if (typeMap) { return typeMap; } - - typeMap = { - idToRecord: {}, - records: [], - metadata: {} - }; - - typeMaps[guid] = typeMap; - - return typeMap; - }, - - // ................ - // . LOADING DATA . - // ................ - - /** - This internal method is used by `push`. - - @method _load - @private - @param {String or subclass of DS.Model} type - @param {Object} data - @param {Boolean} partial the data should be merged into - the existing data, not replace it. - */ - _load: function(type, data, partial) { - var id = coerceId(data.id), - record = this.recordForId(type, id); - - record.setupData(data, partial); - this.recordArrayManager.recordDidChange(record); - - return record; - }, - - /** - Returns a model class for a particular key. Used by - methods that take a type key (like `find`, `createRecord`, - etc.) - - @method modelFor - @param {String or subclass of DS.Model} key - @returns {subclass of DS.Model} - */ - modelFor: function(key) { - var factory; - - - if (typeof key === 'string') { - var normalizedKey = this.container.normalize('model:' + key); - - factory = this.container.lookupFactory(normalizedKey); - if (!factory) { throw new Ember.Error("No model was found for '" + key + "'"); } - factory.typeKey = normalizedKey.split(':', 2)[1]; - } else { - // A factory already supplied. - factory = key; - } - - factory.store = this; - return factory; - }, - - /** - Push some data for a given type into the store. - - This method expects normalized data: - - * The ID is a key named `id` (an ID is mandatory) - * The names of attributes are the ones you used in - your model's `DS.attr`s. - * Your relationships must be: - * represented as IDs or Arrays of IDs - * represented as model instances - * represented as URLs, under the `links` key - - For this model: - - ```js - App.Person = DS.Model.extend({ - firstName: DS.attr(), - lastName: DS.attr(), - - children: DS.hasMany('person') - }); - ``` - - To represent the children as IDs: - - ```js - { - id: 1, - firstName: "Tom", - lastName: "Dale", - children: [1, 2, 3] - } - ``` - - To represent the children relationship as a URL: - - ```js - { - id: 1, - firstName: "Tom", - lastName: "Dale", - links: { - children: "/people/1/children" - } - } - ``` - - If you're streaming data or implementing an adapter, - make sure that you have converted the incoming data - into this form. - - This method can be used both to push in brand new - records, as well as to update existing records. - - @method push - @param {String or subclass of DS.Model} type - @param {Object} data - @returns {DS.Model} the record that was created or - updated. - */ - push: function(type, data, _partial) { - // _partial is an internal param used by `update`. - // If passed, it means that the data should be - // merged into the existing data, not replace it. - - Ember.assert("You must include an `id` in a hash passed to `push`", data.id != null); - - type = this.modelFor(type); - - // normalize relationship IDs into records - data = normalizeRelationships(this, type, data); - - this._load(type, data, _partial); - - return this.recordForId(type, data.id); - }, - - /** - Push some raw data into the store. - - The data will be automatically deserialized using the - serializer for the `type` param. - - This method can be used both to push in brand new - records, as well as to update existing records. - - You can push in more than one type of object at once. - All objects should be in the format expected by the - serializer. - - ```js - App.ApplicationSerializer = DS.ActiveModelSerializer; - - var pushData = { - posts: [ - {id: 1, post_title: "Great post", comment_ids: [2]} - ], - comments: [ - {id: 2, comment_body: "Insightful comment"} - ] - } - - store.pushPayload('post', pushData); - ``` - - @method pushPayload - @param {String} type - @param {Object} payload - @return {DS.Model} the record that was created or updated. - */ - pushPayload: function (type, payload) { - var serializer; - if (!payload) { - payload = type; - serializer = defaultSerializer(this.container); - Ember.assert("You cannot use `store#pushPayload` without a type unless your default serializer defines `pushPayload`", serializer.pushPayload); - } else { - serializer = this.serializerFor(type); - } - serializer.pushPayload(this, payload); - }, - - update: function(type, data) { - Ember.assert("You must include an `id` in a hash passed to `update`", data.id != null); - - return this.push(type, data, true); - }, - - /** - If you have an Array of normalized data to push, - you can call `pushMany` with the Array, and it will - call `push` repeatedly for you. - - @method pushMany - @param {String or subclass of DS.Model} type - @param {Array} datas - @return {Array} - */ - pushMany: function(type, datas) { - return map(datas, function(data) { - return this.push(type, data); - }, this); - }, - - /** - If you have some metadata to set for a type - you can call `metaForType`. - - @method metaForType - @param {String or subclass of DS.Model} type - @param {Object} metadata - */ - metaForType: function(type, metadata) { - type = this.modelFor(type); - - Ember.merge(this.typeMapFor(type).metadata, metadata); - }, - - /** - Build a brand new record for a given type, ID, and - initial data. - - @method buildRecord - @private - @param {subclass of DS.Model} type - @param {String} id - @param {Object} data - @returns {DS.Model} record - */ - buildRecord: function(type, id, data) { - var typeMap = this.typeMapFor(type), - idToRecord = typeMap.idToRecord; - - Ember.assert('The id ' + id + ' has already been used with another record of type ' + type.toString() + '.', !id || !idToRecord[id]); - - // lookupFactory should really return an object that creates - // instances with the injections applied - var record = type._create({ - id: id, - store: this, - container: this.container - }); - - if (data) { - record.setupData(data); - } - - // if we're creating an item, this process will be done - // later, once the object has been persisted. - if (id) { - idToRecord[id] = record; - } - - typeMap.records.push(record); - - return record; - }, - - // ............... - // . DESTRUCTION . - // ............... - - /** - When a record is destroyed, this un-indexes it and - removes it from any record arrays so it can be GCed. - - @method dematerializeRecord - @private - @param {DS.Model} record - */ - dematerializeRecord: function(record) { - var type = record.constructor, - typeMap = this.typeMapFor(type), - id = get(record, 'id'); - - record.updateRecordArrays(); - - if (id) { - delete typeMap.idToRecord[id]; - } - - var loc = indexOf(typeMap.records, record); - typeMap.records.splice(loc, 1); - }, - - // ........................ - // . RELATIONSHIP CHANGES . - // ........................ - - addRelationshipChangeFor: function(childRecord, childKey, pa
<TRUNCATED>