ember-data-source 1.0.0.beta.2 → 1.0.0.beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/dist/ember-data.js +1216 -286
- data/dist/ember-data.min.js +8 -6
- data/dist/ember-data.prod.js +1208 -279
- metadata +4 -4
data/dist/ember-data.min.js
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
// ==========================================================================
|
2
2
|
// Project: Ember Data
|
3
|
-
// Copyright:
|
4
|
-
// Portions
|
3
|
+
// Copyright: Copyright 2011-2013 Tilde Inc. and contributors.
|
4
|
+
// Portions Copyright 2011 LivingSocial Inc.
|
5
5
|
// License: Licensed under MIT license (see license.js)
|
6
6
|
// ==========================================================================
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
-
// Version: v1.0.0-beta.
|
11
|
-
// Last commit:
|
10
|
+
// Version: v1.0.0-beta.3-48-gb47afef
|
11
|
+
// Last commit: b47afef (2013-10-08 19:07:59 -0700)
|
12
12
|
|
13
13
|
|
14
|
-
!function(){var e,t;!function(){var r={},n={};e=function(e,t,n){r[e]={deps:t,callback:n}},t=function(e){if(n[e])return n[e];n[e]={};var i,a,o,s,c;if(i=r[e],!i)throw new Error("Module '"+e+"' not found.");a=i.deps,o=i.callback,s=[];for(var d=0,u=a.length;u>d;d++)"exports"===a[d]?s.push(c={}):s.push(t(a[d]));var l=o.apply(this,s);return n[e]=c||l}}(),function(){"undefined"==typeof DS&&(DS=Ember.Namespace.create({VERSION:"1.0.0-beta.1"}),"undefined"!=typeof window&&(window.DS=DS))}(),function(){function e(e){return function(){return this[e].apply(this,arguments)}}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.JSONSerializer=Ember.Object.extend({primaryKey:"id",applyTransforms:function(e,t){return e.eachTransformedAttribute(function(e,r){var n=this.transformFor(r);t[e]=n.deserialize(t[e])},this),t},normalize:function(e,t){return t?(this.applyTransforms(e,t),t):t},serialize:function(e,r){t(this,"store");var n={};if(r&&r.includeId){var i=t(e,"id");i&&(n[t(this,"primaryKey")]=t(e,"id"))}return e.eachAttribute(function(t,r){this.serializeAttribute(e,n,t,r)},this),e.eachRelationship(function(t,r){"belongsTo"===r.kind?this.serializeBelongsTo(e,n,r):"hasMany"===r.kind&&this.serializeHasMany(e,n,r)},this),n},serializeAttribute:function(e,r,n,i){var a=t(this,"attrs"),o=t(e,n),s=i.type;if(s){var c=this.transformFor(s);o=c.serialize(o)}n=a&&a[n]||n,r[n]=o},serializeBelongsTo:function(e,n,i){var a=i.key,o=t(e,a);r(o)||(n[a]=t(o,"id"),i.options.polymorphic&&(n[a+"_type"]=o.constructor.typeKey))},serializeHasMany:function(e,r,n){var i=n.key,a=DS.RelationshipChange.determineRelationshipType(e.constructor,n);("manyToNone"===a||"manyToMany"===a)&&(r[i]=t(e,i).mapBy("id"))},extract:function(e,t,r,n,i){this.extractMeta(e,t,r);var a="extract"+i.charAt(0).toUpperCase()+i.substr(1);return this[a](e,t,r,n,i)},extractFindAll:e("extractArray"),extractFindQuery:e("extractArray"),extractFindMany:e("extractArray"),extractFindHasMany:e("extractArray"),extractCreateRecord:e("extractSave"),extractUpdateRecord:e("extractSave"),extractDeleteRecord:e("extractSave"),extractFind:e("extractSingle"),extractSave:e("extractSingle"),extractSingle:function(e,t,r){return this.normalize(t,r)},extractArray:function(e,t,r){return this.normalize(t,r)},extractMeta:function(e,t,r){r&&r.meta&&(e.metaForType(t,r.meta),delete r.meta)},typeFor:function(e,t,r){return e.options.polymorphic?r[t+"_type"]:e.type},transformFor:function(e){return this.container.lookup("transform:"+e)}})}(),function(){var e=Ember.get,t=Ember.String.capitalize,r=Ember.String.underscore,n=window.DS;n.DebugAdapter=Ember.DataAdapter.extend({getFilters:function(){return[{name:"isNew",desc:"New"},{name:"isModified",desc:"Modified"},{name:"isClean",desc:"Clean"}]},detect:function(e){return e!==n.Model&&n.Model.detect(e)},columnsForType:function(n){var i=[{name:"id",desc:"Id"}],a=0,o=this;return Ember.A(e(n,"attributes")).forEach(function(e){if(a++>o.attributeLimit)return!1;var n=t(r(e).replace("_"," "));i.push({name:e,desc:n})}),i},getRecords:function(e){return this.get("store").all(e)},getRecordColumnValues:function(t){var r=this,n=0,i={id:e(t,"id")};return t.eachAttribute(function(a){if(n++>r.attributeLimit)return!1;var o=e(t,a);i[a]=o}),i},getRecordKeywords:function(t){var r=[],n=Ember.A(["id"]);return t.eachAttribute(function(e){n.push(e)}),n.forEach(function(n){r.push(e(t,n))}),r},getRecordFilterValues:function(e){return{isNew:e.get("isNew"),isModified:e.get("isDirty")&&!e.get("isNew"),isClean:!e.get("isDirty")}},getRecordColor:function(e){var t="black";return e.get("isNew")?t="green":e.get("isDirty")&&(t="blue"),t},observeRecord:function(e,t){var r=Ember.A(),n=this,i=Ember.A(["id","isNew","isDirty"]);e.eachAttribute(function(e){i.push(e)}),i.forEach(function(i){var a=function(){t(n.wrapRecord(e))};Ember.addObserver(e,i,a),r.push(function(){Ember.removeObserver(e,i,a)})});var a=function(){r.forEach(function(e){e()})};return a}})}(),function(){DS.Transform=Ember.Object.extend({serialize:Ember.required(),deserialize:Ember.required()})}(),function(){DS.BooleanTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"boolean"===t?e:"string"===t?null!==e.match(/^true$|^t$|^1$/i):"number"===t?1===e:!1},serialize:function(e){return Boolean(e)}})}(),function(){DS.DateTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"string"===t?new Date(Ember.Date.parse(e)):"number"===t?new Date(e):null===e||void 0===e?e:null},serialize:function(e){if(e instanceof Date){var t=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],r=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],n=function(e){return 10>e?"0"+e:""+e},i=e.getUTCFullYear(),a=e.getUTCMonth(),o=e.getUTCDate(),s=e.getUTCDay(),c=e.getUTCHours(),d=e.getUTCMinutes(),u=e.getUTCSeconds(),l=t[s],h=n(o),f=r[a];return l+", "+h+" "+f+" "+i+" "+n(c)+":"+n(d)+":"+n(u)+" GMT"}return null}})}(),function(){var e=Ember.isEmpty;DS.NumberTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:Number(t)},serialize:function(t){return e(t)?null:Number(t)}})}(),function(){var e=Ember.isNone;Ember.isEmpty,DS.StringTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:String(t)},serialize:function(t){return e(t)?null:String(t)}})}(),function(){Ember.set,Ember.onLoad("Ember.Application",function(e){e.initializer({name:"store",initialize:function(e,t){t.register("store:main",t.Store||DS.Store),t.register("serializer:_default",DS.JSONSerializer),t.register("serializer:_rest",DS.RESTSerializer),t.register("adapter:_rest",DS.RESTAdapter),e.lookup("store:main")}}),e.initializer({name:"transforms",initialize:function(e,t){t.register("transform:boolean",DS.BooleanTransform),t.register("transform:date",DS.DateTransform),t.register("transform:number",DS.NumberTransform),t.register("transform:string",DS.StringTransform)}}),e.initializer({name:"dataAdapter",initialize:function(e,t){t.register("dataAdapter:main",DS.DebugAdapter)}}),e.initializer({name:"injectStore",initialize:function(e,t){t.inject("controller","store","store:main"),t.inject("route","store","store:main"),t.inject("serializer","store","store:main"),t.inject("dataAdapter","store","store:main")}})})}(),function(){Ember.Date=Ember.Date||{};var e=Date.parse,t=[1,4,5,6,7,10,11];Ember.Date.parse=function(r){var n,i,a=0;if(i=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(r)){for(var o,s=0;o=t[s];++s)i[o]=+i[o]||0;i[2]=(+i[2]||1)-1,i[3]=+i[3]||1,"Z"!==i[8]&&void 0!==i[9]&&(a=60*i[10]+i[11],"+"===i[9]&&(a=0-a)),n=Date.UTC(i[1],i[2],i[3],i[4],i[5]+a,i[6],i[7])}else n=e?e(r):0/0;return n},(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.Date)&&(Date.parse=Ember.Date.parse)}(),function(){var e=Ember.get;Ember.set,DS.RecordArray=Ember.ArrayProxy.extend(Ember.Evented,{type:null,content:null,isLoaded:!1,isUpdating:!1,store:null,objectAtContent:function(t){var r=e(this,"content");return r.objectAt(t)},update:function(){if(!e(this,"isUpdating")){var t=e(this,"store"),r=e(this,"type");t.fetchAll(r,this)}},addRecord:function(t){e(this,"content").addObject(t)},removeRecord:function(t){e(this,"content").removeObject(t)}})}(),function(){var e=Ember.get;DS.FilteredRecordArray=DS.RecordArray.extend({filterFunction:null,isLoaded:!0,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a client-side filter (on "+t+") is immutable.")},updateFilter:Ember.observer(function(){var t=e(this,"manager");t.updateFilter(this,e(this,"type"),e(this,"filterFunction"))},"filterFunction")})}(),function(){var e=Ember.get;Ember.set,DS.AdapterPopulatedRecordArray=DS.RecordArray.extend({query:null,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a server query (on "+t+") is immutable.")},load:function(t){var r=e(this,"store"),n=e(this,"type"),i=r.pushMany(n,t);this.setProperties({content:Ember.A(i),isLoaded:!0}),Ember.run.once(this,"trigger","didLoad")}})}(),function(){var e=Ember.get,t=Ember.set,r=Ember.EnumerableUtils.map;DS.ManyArray=DS.RecordArray.extend({init:function(){this._super.apply(this,arguments),this._changesToSync=Ember.OrderedSet.create()},owner:null,isPolymorphic:!1,isLoaded:!1,loadingRecordsCount:function(e){this.loadingRecordsCount=e},loadedRecord:function(){this.loadingRecordsCount--,0===this.loadingRecordsCount&&(t(this,"isLoaded",!0),this.trigger("didLoad"))},fetch:function(){var t=e(this,"content"),r=e(this,"store"),n=e(this,"owner"),i=t.filterProperty("isEmpty",!0);r.fetchMany(i,n)},replaceContent:function(e,t,n){n=r(n,function(e){return e},this),this._super(e,t,n)},arrangedContentDidChange:function(){this.fetch()},arrayContentWillChange:function(t,r){var n=e(this,"owner"),i=e(this,"name");if(!n._suspendedRelationships)for(var a=t;t+r>a;a++){var o=e(this,"content").objectAt(a),s=DS.RelationshipChange.createChange(n,o,e(this,"store"),{parentType:n.constructor,changeType:"remove",kind:"hasMany",key:i});this._changesToSync.add(s)}return this._super.apply(this,arguments)},arrayContentDidChange:function(t,r,n){this._super.apply(this,arguments);var i=e(this,"owner"),a=e(this,"name"),o=e(this,"store");if(!i._suspendedRelationships){for(var s=t;t+n>s;s++){var c=e(this,"content").objectAt(s),d=DS.RelationshipChange.createChange(i,c,o,{parentType:i.constructor,changeType:"add",kind:"hasMany",key:a});d.hasManyName=a,this._changesToSync.add(d)}this._changesToSync.forEach(function(e){e.sync()}),this._changesToSync.clear()}},createRecord:function(t){var r,n=e(this,"owner"),i=e(n,"store"),a=e(this,"type");return r=i.createRecord.call(i,a,t),this.pushObject(r),r}})}(),function(){function e(e){var t=Ember.meta(e,!0),r="DS.Mappable",n=t[r];return n||(t[r]={}),t.hasOwnProperty(r)||(t[r]=Ember.create(t[r])),t[r]}Ember.get;var t=Ember.ArrayPolyfills.forEach,r=function(e){return e},n=function(e){return e},i=function(e,t){return t};DS._Mappable=Ember.Mixin.create({createInstanceMapFor:function(t){var r=e(this);if(r.values=r.values||{},r.values[t])return r.values[t];for(var n=r.values[t]=new Ember.Map,i=this.constructor;i&&i!==DS.Store;)this._copyMap(t,i,n),i=i.superclass;return r.values[t]=n,n},_copyMap:function(a,o,s){function c(e,t){var a=(o.transformMapKey||n)(e,t),c=(o.transformMapValue||i)(e,t),d=s.get(a),u=c;d&&(u=(this.constructor.resolveMapConflict||r)(d,u)),s.set(a,u)}var d=e(o),u=d[a];u&&t.call(u,c,this)}}),DS._Mappable.generateMapFunctionFor=function(t,r){return function(n,i){var a=e(this),o=a[t]||Ember.MapWithDefault.create({defaultValue:function(){return{}}});r.call(this,n,i,o),a[t]=o}}}(),function(){function e(e,r,i){return r.eachRelationship(function(r,a){if(!i.links||!i.links[r]){var o=(a.type,i[r]);null!=o&&("belongsTo"===a.kind?t(e,i,r,a,o):"hasMany"===a.kind&&n(e,i,r,a,o))}}),i}function t(e,t,n,i,a){if(!(g(a)||a instanceof DS.Model)){var o;"number"==typeof a||"string"==typeof a?(o=r(i,n,t),t[n]=e.recordForId(o,a)):"object"==typeof a&&(t[n]=e.recordForId(a.type,a.id))}}function r(e,t,r){return e.options.polymorphic?r[t+"_type"]:e.type}function n(e,r,n,i,a){for(var o=0,s=a.length;s>o;o++)t(e,a,o,i,a[o])}function i(e){return DS.PromiseObject.create({promise:e})}function a(e){return DS.PromiseArray.create({promise:e})}function o(e,t,r){return e.lookup("serializer:"+t)||e.lookup("serializer:application")||e.lookup("serializer:"+r)||e.lookup("serializer:_default")}function s(e,t){var r=e.serializer,n=e.defaultSerializer,i=e.container;return i&&void 0===r&&(r=o(i,t.typeKey,n)),(null===r||void 0===r)&&(r={extract:function(e,t,r){return r}}),r}function c(e,t,r,n,i){var a=e.find(t,r,n),o=s(e,r);return E(a).then(function(e){return e=o.extract(t,r,e,n,"find"),t.push(r,e)}).then(i.resolve,i.reject)}function d(e,t,r,n,i,a){var o=e.findMany(t,r,n,i),c=s(e,r);return E(o).then(function(e){e=c.extract(t,r,e,null,"findMany"),t.pushMany(r,e)}).then(a.resolve,a.reject)}function u(e,t,r,n,i,a){var o=e.findHasMany(t,r,n,i),c=s(e,i.type);return E(o).then(function(e){e=c.extract(t,i.type,e,null,"findHasMany");var n=t.pushMany(i.type,e);r.updateHasMany(i.key,n)}).then(a.resolve,a.reject)}function l(e,t,r,n,i){var a=e.findAll(t,r,n),o=s(e,r);return E(a).then(function(e){return e=o.extract(t,r,e,null,"findAll"),t.pushMany(r,e),t.didUpdateAll(r),t.all(r)}).then(i.resolve,i.reject)}function h(e,t,r,n,i,a){var o=e.findQuery(t,r,n,i),c=s(e,r);return E(o).then(function(e){return e=c.extract(t,r,e,null,"findAll"),i.load(e),i}).then(a.resolve,a.reject)}function f(e,t,r,n,i){var a=n.constructor,o=e[r](t,a,n),c=s(e,a);return o.then(function(e){return e=c.extract(t,a,e,p(n,"id"),r),t.didSaveRecord(n,e),n},function(e){throw e instanceof DS.InvalidError?t.recordWasInvalid(n,e.errors):t.recordWasError(n,e),e}).then(i.resolve,i.reject)}var p=Ember.get,m=Ember.set,y=Ember.run.once,g=Ember.isNone,b=Ember.EnumerableUtils.forEach,v=Ember.EnumerableUtils.indexOf,R=Ember.EnumerableUtils.map;Ember.OrderedSet;var E=Ember.RSVP.resolve,S=function(e){return null==e?null:e+""};DS.Store=Ember.Object.extend(DS._Mappable,{init:function(){this.typeMaps={},this.recordArrayManager=DS.RecordArrayManager.create({store:this}),this._relationshipChanges={},this._pendingSave=[]},adapter:"_rest",serialize:function(e,t){return this.serializerFor(e.constructor.typeKey).serialize(e,t)},defaultAdapter:Ember.computed(function(){var e=p(this,"adapter");return"string"==typeof e&&(e=this.container.lookup("adapter:"+e)||this.container.lookup("adapter:application")||this.container.lookup("adapter:_rest")),DS.Adapter.detect(e)&&(e=e.create({container:this.container})),e}).property("adapter"),createRecord:function(e,t){e=this.modelFor(e),t=t||{},g(t.id)&&(t.id=this._generateId(e)),t.id=S(t.id);var r=this.buildRecord(e,t.id);return r.loadedData(),r.setProperties(t),r},_generateId:function(e){var t=this.adapterForType(e);return t&&t.generateIdForRecord?t.generateIdForRecord(this):null},deleteRecord:function(e){e.deleteRecord()},unloadRecord:function(e){e.unloadRecord()},find:function(e,t){return void 0===t?this.findAll(e):"object"===Ember.typeOf(t)?this.findQuery(e,t):this.findById(e,S(t))},findById:function(e,t){e=this.modelFor(e);var r=this.getById(e,t);return p(r,"isEmpty")?i(this.fetchRecord(r)):i(E(r))},findByIds:function(e,t){var r=this;return a(Ember.RSVP.all(R(t,function(t){return r.findById(e,t)})).then(function(e){return Ember.A(e)}))},fetchRecord:function(e){var t=e.constructor,r=p(e,"id"),n=Ember.RSVP.defer();e.loadingData();var i=this.adapterForType(t);return c(i,this,t,r,n),n.promise},getById:function(e,t){return e=this.modelFor(e),this.hasRecordForId(e,t)?this.recordForId(e,t):this.buildRecord(e,t)},reloadRecord:function(e,t){var r=e.constructor,n=this.adapterForType(r),i=p(e,"id");return c(n,this,r,i,t)},fetchMany:function(e,t,r){if(e.length){var n=Ember.MapWithDefault.create({defaultValue:function(){return Ember.A()}});b(e,function(e){n.get(e.constructor).push(e)}),b(n,function(e,n){var i=n.mapProperty("id"),a=this.adapterForType(e);d(a,this,e,i,t,r)},this)}},hasRecordForId:function(e,t){return t=S(t),!!this.typeMapFor(e).idToRecord[t]},recordForId:function(e,t){e=this.modelFor(e),t=S(t);var r=this.typeMapFor(e).idToRecord[t];return r||(r=this.buildRecord(e,t)),r},findMany:function(e,t,r,n){r=this.modelFor(r),t=Ember.A(t);var i=t.filterProperty("isEmpty",!0),a=this.recordArrayManager.createManyArray(r,t);return b(i,function(e){e.loadingData()}),a.loadingRecordsCount=i.length,i.length?(b(i,function(e){this.recordArrayManager.registerWaitingRecordArray(e,a)},this),this.fetchMany(i,e,n)):(n&&n.resolve(),a.set("isLoaded",!0),Ember.run.once(a,"trigger","didLoad")),a},findHasMany:function(e,t,r,n){var i=this.adapterForType(e.constructor),a=this.recordArrayManager.createManyArray(r.type,Ember.A([]));return u(i,this,e,t,r,n),a},findQuery:function(e,t){e=this.modelFor(e);var r=DS.AdapterPopulatedRecordArray.create({type:e,query:t,content:Ember.A(),store:this}),n=this.adapterForType(e),i=Ember.RSVP.defer();return h(n,this,e,t,r,i),a(i.promise)},findAll:function(e){return e=this.modelFor(e),this.fetchAll(e,this.all(e))},fetchAll:function(e,t){var r=this.adapterForType(e),n=this.typeMapFor(e).metadata.since,i=Ember.RSVP.defer();return m(t,"isUpdating",!0),l(r,this,e,n,i),a(i.promise)},didUpdateAll:function(e){var t=this.typeMapFor(e).findAllCache;m(t,"isUpdating",!1)},all:function(e){e=this.modelFor(e);var t=this.typeMapFor(e),r=t.findAllCache;if(r)return r;var n=DS.RecordArray.create({type:e,content:Ember.A(),store:this,isLoaded:!0});return this.recordArrayManager.registerFilteredRecordArray(n,e),t.findAllCache=n,n},filter:function(e,t,r){var n;3===arguments.length?n=this.findQuery(e,t):2===arguments.length&&(r=t),e=this.modelFor(e);var i=DS.FilteredRecordArray.create({type:e,content:Ember.A(),store:this,manager:this.recordArrayManager,filterFunction:r});return this.recordArrayManager.registerFilteredRecordArray(i,e,r),n?n.then(function(){return i}):i},recordIsLoaded:function(e,t){return this.hasRecordForId(e,t)?!p(this.recordForId(e,t),"isEmpty"):!1},dataWasUpdated:function(e,t){p(t,"isDeleted")||p(t,"isLoaded")&&this.recordArrayManager.recordDidChange(t)},scheduleSave:function(e,t){e.adapterWillCommit(),this._pendingSave.push([e,t]),y(this,"flushPendingSave")},flushPendingSave:function(){var e=this._pendingSave.slice();this._pendingSave=[],b(e,function(e){var t,r=e[0],n=e[1],i=this.adapterForType(r.constructor);t=p(r,"isNew")?"createRecord":p(r,"isDeleted")?"deleteRecord":"updateRecord",f(i,this,t,r,n)},this)},didSaveRecord:function(e,t){t&&this.updateId(e,t),e.adapterDidCommit(t)},recordWasInvalid:function(e,t){e.adapterDidInvalidate(t)},recordWasError:function(e){e.adapterDidError()},updateId:function(e,t){var r=(p(e,"id"),S(t.id));this.typeMapFor(e.constructor).idToRecord[r]=e,m(e,"id",r)},typeMapFor:function(e){var t,r=p(this,"typeMaps"),n=Ember.guidFor(e);return(t=r[n])?t:(t={idToRecord:{},records:[],metadata:{}},r[n]=t,t)},_load:function(e,t,r){var n=S(t.id),i=this.recordForId(e,n);return i.setupData(t,r),this.recordArrayManager.recordDidChange(i),i},modelFor:function(e){if("string"!=typeof e)return e;var t=this.container.lookupFactory("model:"+e);return t.store=this,t.typeKey=e,t},push:function(t,r,n){return this.serializerFor(t),t=this.modelFor(t),r=e(this,t,r),this._load(t,r,n),this.recordForId(t,r.id)},update:function(e,t){return this.push(e,t,!0)},pushMany:function(e,t){return R(t,function(t){return this.push(e,t)},this)},metaForType:function(e,t){e=this.modelFor(e),Ember.merge(this.typeMapFor(e).metadata,t)},buildRecord:function(e,t,r){var n=this.typeMapFor(e),i=n.idToRecord,a=e._create({id:t,store:this});return r&&a.setupData(r),t&&(i[t]=a),n.records.push(a),a},dematerializeRecord:function(e){var t=e.constructor,r=this.typeMapFor(t),n=p(e,"id");e.updateRecordArrays(),n&&delete r.idToRecord[n];var i=v(r.records,e);r.records.splice(i,1)},addRelationshipChangeFor:function(e,t,r,n,i){var a=e.clientId,o=r?r:r,s=t+n,c=this._relationshipChanges;a in c||(c[a]={}),o in c[a]||(c[a][o]={}),s in c[a][o]||(c[a][o][s]={}),c[a][o][s][i.changeType]=i},removeRelationshipChangeFor:function(e,t,r,n,i){var a=e.clientId,o=r?r.clientId:r,s=this._relationshipChanges,c=t+n;a in s&&o in s[a]&&c in s[a][o]&&delete s[a][o][c][i]},relationshipChangePairsFor:function(e){var t=[];if(!e)return t;var r=this._relationshipChanges[e.clientId];for(var n in r)if(r.hasOwnProperty(n))for(var i in r[n])r[n].hasOwnProperty(i)&&t.push(r[n][i]);return t},adapterForType:function(e){var t,r=this.container;return r&&(t=r.lookup("adapter:"+e.typeKey)||r.lookup("adapter:application")),t||p(this,"defaultAdapter")},serializerFor:function(e){e=this.modelFor(e);var t=this.adapterForType(e);return o(this.container,e.typeKey,t&&t.defaultSerializer)}}),DS.PromiseArray=Ember.ArrayProxy.extend(Ember.PromiseProxyMixin),DS.PromiseObject=Ember.ObjectProxy.extend(Ember.PromiseProxyMixin)}(),function(){function e(t){var r,n={};for(var i in t)r=t[i],n[i]=r&&"object"==typeof r?e(r):r;return n}function t(e,t){for(var r in t)e[r]=t[r];return e}function r(r){var n=e(c);return t(n,r)}function n(e,r,i){e=t(r?Ember.create(r):{},e),e.parentState=r,e.stateName=i;for(var a in e)e.hasOwnProperty(a)&&"parentState"!==a&&"stateName"!==a&&"object"==typeof e[a]&&(e[a]=n(e[a],e,i+"."+a));return e}var i=Ember.get,a=Ember.set;Ember.run.once,Ember.ArrayPolyfills.map;var o=function(e){var t,r,n,i=Ember.keys(e);for(t=0,r=i.length;r>t;t++)if(n=i[t],e.hasOwnProperty(n)&&e[n])return!0;return!1},s=function(e,t){t.value!==t.oldValue&&(e.send("becomeDirty"),e.updateRecordArraysLater())},c={initialState:"uncommitted",isDirty:!0,uncommitted:{didSetProperty:s,pushedData:Ember.K,becomeDirty:Ember.K,willCommit:function(e){e.transitionTo("inFlight")},reloadRecord:function(e,t){i(e,"store").reloadRecord(e,t)},rolledBack:function(e){e.transitionTo("loaded.saved")},becameInvalid:function(e){e.transitionTo("invalid")},rollback:function(e){e.rollback()}},inFlight:{isSaving:!0,didSetProperty:s,becomeDirty:Ember.K,pushedData:Ember.K,willCommit:Ember.K,didCommit:function(e){var t=i(this,"dirtyType");e.transitionTo("saved"),e.send("invokeLifecycleCallbacks",t)},becameInvalid:function(e,t){a(e,"errors",t),e.transitionTo("invalid"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},invalid:{isValid:!1,deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},didSetProperty:function(e,t){var r=i(e,"errors"),n=t.name;a(r,n,null),o(r)||e.send("becameValid"),s(e,t)},becomeDirty:Ember.K,rollback:function(e){e.send("becameValid"),e.send("rollback")},becameValid:function(e){e.transitionTo("uncommitted")},invokeLifecycleCallbacks:function(e){e.triggerLater("becameInvalid",e)}}},d=r({dirtyType:"created",isNew:!0});d.uncommitted.rolledBack=function(e){e.transitionTo("deleted.saved")};var u=r({dirtyType:"updated"});d.uncommitted.deleteRecord=function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},d.uncommitted.rollback=function(e){c.uncommitted.rollback.apply(this,arguments),e.transitionTo("deleted.saved")},u.uncommitted.deleteRecord=function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()};var l={isEmpty:!1,isLoading:!1,isLoaded:!1,isDirty:!1,isSaving:!1,isDeleted:!1,isNew:!1,isValid:!0,rolledBack:Ember.K,empty:{isEmpty:!0,loadingData:function(e){e.transitionTo("loading")},loadedData:function(e){e.transitionTo("loaded.created.uncommitted"),e.suspendRelationshipObservers(function(){e.notifyPropertyChange("data")})},pushedData:function(e){e.transitionTo("loaded.saved")}},loading:{isLoading:!0,pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad"),a(e,"isError",!1)},becameError:function(e){e.triggerLater("becameError",e)}},loaded:{initialState:"saved",isLoaded:!0,saved:{setup:function(e){var t=e._attributes,r=!1;for(var n in t)if(t.hasOwnProperty(n)){r=!0;break}r&&e.adapterDidDirty()},didSetProperty:s,pushedData:Ember.K,becomeDirty:function(e){e.transitionTo("updated.uncommitted")},willCommit:function(e){e.transitionTo("updated.inFlight")},reloadRecord:function(e,t){i(e,"store").reloadRecord(e,t)},deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},unloadRecord:function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},didCommit:function(e){e.send("invokeLifecycleCallbacks",i(e,"lastDirtyType"))}},created:d,updated:u},deleted:{initialState:"uncommitted",dirtyType:"deleted",isDeleted:!0,isLoaded:!0,isDirty:!0,setup:function(e){var t=i(e,"store");t.recordArrayManager.remove(e)},uncommitted:{willCommit:function(e){e.transitionTo("inFlight")},rollback:function(e){e.rollback()},becomeDirty:Ember.K,deleteRecord:Ember.K,rolledBack:function(e){e.transitionTo("loaded.saved")}},inFlight:{isSaving:!0,willCommit:Ember.K,didCommit:function(e){e.transitionTo("saved"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},saved:{isDirty:!1,setup:function(e){var t=i(e,"store");t.dematerializeRecord(e)},invokeLifecycleCallbacks:function(e){e.triggerLater("didDelete",e),e.triggerLater("didCommit",e)}}},invokeLifecycleCallbacks:function(e,t){"created"===t?e.triggerLater("didCreate",e):e.triggerLater("didUpdate",e),e.triggerLater("didCommit",e)}};({}).hasOwnProperty,l=n(l,null,"root"),DS.RootState=l}(),function(){var e=Ember.get,t=Ember.set,r=(Ember.EnumerableUtils.map,Ember.merge),n=Ember.run.once;Ember.ArrayPolyfills.map;var i=Ember.computed(function(t){return e(e(this,"currentState"),t)}).property("currentState").readOnly();DS.Model=Ember.Object.extend(Ember.Evented,{isEmpty:i,isLoading:i,isLoaded:i,isDirty:i,isSaving:i,isDeleted:i,isNew:i,isValid:i,dirtyType:i,isError:!1,isReloading:!1,clientId:null,id:null,transaction:null,currentState:null,errors:null,serialize:function(t){var r=e(this,"store");return r.serialize(this,t)},toJSON:function(e){var t=DS.JSONSerializer.create();return t.serialize(this,e)},didLoad:Ember.K,didReload:Ember.K,didUpdate:Ember.K,didCreate:Ember.K,didDelete:Ember.K,becameInvalid:Ember.K,becameError:Ember.K,data:Ember.computed(function(){return this._data=this._data||{},this._data}).property(),_data:null,init:function(){t(this,"currentState",DS.RootState.empty),this._super(),this._setup()},_setup:function(){this._changesToSync={},this._deferredTriggers=[],this._data={},this._attributes={},this._inFlightAttributes={},this._relationships={}},send:function(t,r){var n=e(this,"currentState");return n[t]||this._unhandledEvent(n,t,r),n[t](this,r)},transitionTo:function(r){var n=r.split(".",1),i=e(this,"currentState"),a=i;do a.exit&&a.exit(this),a=a.parentState;while(!a.hasOwnProperty(n));var o,s,c=r.split("."),d=[],u=[];for(o=0,s=c.length;s>o;o++)a=a[c[o]],a.enter&&u.push(a),a.setup&&d.push(a);for(o=0,s=u.length;s>o;o++)u[o].enter(this);for(t(this,"currentState",a),o=0,s=d.length;s>o;o++)d[o].setup(this)},_unhandledEvent:function(e,t,r){var n="Attempted to handle event `"+t+"` ";throw n+="on "+String(this)+" while in state ",n+=e.stateName+". ",void 0!==r&&(n+="Called with "+Ember.inspect(r)+"."),new Ember.Error(n)},withTransaction:function(t){var r=e(this,"transaction");r&&t(r)},loadingData:function(){this.send("loadingData")},loadedData:function(){this.send("loadedData")},pushedData:function(){this.send("pushedData")},deleteRecord:function(){this.send("deleteRecord")},unloadRecord:function(){this.send("unloadRecord")},clearRelationships:function(){this.eachRelationship(function(e,r){if("belongsTo"===r.kind)t(this,e,null);else if("hasMany"===r.kind){var n=this._relationships[r.name];n&&n.clear()}},this)},updateRecordArrays:function(){var t=e(this,"store");t&&t.dataWasUpdated(this.constructor,this)},adapterWillCommit:function(){this.send("willCommit")},adapterDidCommit:function(e){t(this,"isError",!1),e?this._data=e:Ember.mixin(this._data,this._inFlightAttributes),this._inFlightAttributes={},this.send("didCommit"),this.updateRecordArraysLater(),e&&this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},adapterDidDirty:function(){this.send("becomeDirty"),this.updateRecordArraysLater()},dataDidChange:Ember.observer(function(){this.reloadHasManys()},"data"),reloadHasManys:function(){var t=e(this.constructor,"relationshipsByName");this.updateRecordArraysLater(),t.forEach(function(e,t){"hasMany"===t.kind&&this.hasManyDidChange(t.key)},this)},hasManyDidChange:function(r){var n=this._relationships[r];if(n){e(this.constructor,"relationshipsByName").get(r).type,e(this,"store");var i=this._data[r]||[];t(n,"content",Ember.A(i)),t(n,"isLoaded",!0),n.trigger("didLoad")}},updateRecordArraysLater:function(){Ember.run.once(this,this.updateRecordArrays)},setupData:function(e,t){t?Ember.merge(this._data,e):this._data=e;var r=this._relationships;this.eachRelationship(function(e,t){t.options.async&&(r[e]=null)}),e&&this.pushedData(),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},materializeId:function(e){t(this,"id",e)},materializeAttributes:function(e){r(this._data,e)},materializeAttribute:function(e,t){this._data[e]=t},updateHasMany:function(e,t){this._data[e]=t,this.hasManyDidChange(e)},rollback:function(){this._attributes={},this.send("rolledBack"),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},toStringExtension:function(){return e(this,"id")},suspendRelationshipObservers:function(t,r){var n=e(this.constructor,"relationshipNames").belongsTo,i=this;try{this._suspendedRelationships=!0,Ember._suspendObservers(i,n,null,"belongsToDidChange",function(){Ember._suspendBeforeObservers(i,n,null,"belongsToWillChange",function(){t.call(r||i)})})}finally{this._suspendedRelationships=!1}},save:function(){var e=Ember.RSVP.defer();return this.get("store").scheduleSave(this,e),this._inFlightAttributes=this._attributes,this._attributes={},DS.PromiseObject.create({promise:e.promise})},reload:function(){t(this,"isReloading",!0);var e=Ember.RSVP.defer(),r=this;return e.promise=e.promise.then(function(){return r.set("isReloading",!1),r.set("isError",!1),r},function(e){throw r.set("isError",!0),e}),this.send("reloadRecord",e),DS.PromiseObject.create({promise:e.promise})},adapterDidUpdateAttribute:function(e,t){void 0!==t?(this._data[e]=t,this.notifyPropertyChange(e)):this._data[e]=this._inFlightAttributes[e],this.updateRecordArraysLater()},adapterDidInvalidate:function(e){this.send("becameInvalid",e)},adapterDidError:function(){this.send("becameError"),t(this,"isError",!0)},trigger:function(e){Ember.tryInvoke(this,e,[].slice.call(arguments,1)),this._super.apply(this,arguments)},triggerLater:function(){this._deferredTriggers.push(arguments),n(this,"_triggerDeferredTriggers")},_triggerDeferredTriggers:function(){for(var e=0,t=this._deferredTriggers.length;t>e;e++)this.trigger.apply(this,this._deferredTriggers[e]);this._deferredTriggers=[]}}),DS.Model.reopenClass({_create:DS.Model.create,create:function(){throw new Ember.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.")}})}(),function(){function e(e,t){return"function"==typeof t.defaultValue?t.defaultValue():t.defaultValue}function t(e,t){return e._attributes.hasOwnProperty(t)||e._inFlightAttributes.hasOwnProperty(t)||e._data.hasOwnProperty(t)}function r(e,t){return e._attributes.hasOwnProperty(t)?e._attributes[t]:e._inFlightAttributes.hasOwnProperty(t)?e._inFlightAttributes[t]:e._data[t]}var n=Ember.get;DS.Model.reopenClass({attributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isAttribute&&(r.name=t,e.set(t,r))}),e}),transformedAttributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachAttribute(function(t,r){r.type&&e.set(t,r.type)}),e}),eachAttribute:function(e,t){n(this,"attributes").forEach(function(r,n){e.call(t,r,n)},t)},eachTransformedAttribute:function(e,t){n(this,"transformedAttributes").forEach(function(r,n){e.call(t,r,n)})}}),DS.Model.reopen({eachAttribute:function(e,t){this.constructor.eachAttribute(e,t)}}),DS.attr=function(n,i){i=i||{};var a={type:n,isAttribute:!0,options:i};return Ember.computed(function(n,a){return arguments.length>1?(this.send("didSetProperty",{name:n,oldValue:this._attributes[n]||this._inFlightAttributes[n]||this._data[n],value:a}),this._attributes[n]=a,a):t(this,n)?r(this,n):e(this,i,n)}).property("data").meta(a)}}(),function(){var e=DS.AttributeChange=function(e){this.record=e.record,this.store=e.store,this.name=e.name,this.value=e.value,this.oldValue=e.oldValue};e.createChange=function(t){return new e(t)},e.prototype={sync:function(){this.value!==this.oldValue&&(this.record.send("becomeDirty"),this.record.updateRecordArraysLater()),this.destroy()},destroy:function(){delete this.record._changesToSync[this.name]}}}(),function(){function e(e){return"object"==typeof e&&(!e.then||"function"!=typeof e.then)}var t=Ember.get,r=Ember.set,n=Ember.EnumerableUtils.forEach;DS.RelationshipChange=function(e){this.parentRecord=e.parentRecord,this.childRecord=e.childRecord,this.firstRecord=e.firstRecord,this.firstRecordKind=e.firstRecordKind,this.firstRecordName=e.firstRecordName,this.secondRecord=e.secondRecord,this.secondRecordKind=e.secondRecordKind,this.secondRecordName=e.secondRecordName,this.changeType=e.changeType,this.store=e.store,this.committed={}},DS.RelationshipChangeAdd=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChangeRemove=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChange.create=function(e){return new DS.RelationshipChange(e)},DS.RelationshipChangeAdd.create=function(e){return new DS.RelationshipChangeAdd(e)},DS.RelationshipChangeRemove.create=function(e){return new DS.RelationshipChangeRemove(e)},DS.OneToManyChange={},DS.OneToNoneChange={},DS.ManyToNoneChange={},DS.OneToOneChange={},DS.ManyToManyChange={},DS.RelationshipChange._createChange=function(e){return"add"===e.changeType?DS.RelationshipChangeAdd.create(e):"remove"===e.changeType?DS.RelationshipChangeRemove.create(e):void 0
|
15
|
-
},DS.RelationshipChange.determineRelationshipType=function(e,t){var r,n,i=t.key,a=t.kind,o=e.inverseFor(i);return o&&(r=o.name,n=o.kind),o?"belongsTo"===n?"belongsTo"===a?"oneToOne":"manyToOne":"belongsTo"===a?"oneToMany":"manyToMany":"belongsTo"===a?"oneToNone":"manyToNone"},DS.RelationshipChange.createChange=function(e,t,r,n){var i,a=e.constructor;return i=DS.RelationshipChange.determineRelationshipType(a,n),"oneToMany"===i?DS.OneToManyChange.createChange(e,t,r,n):"manyToOne"===i?DS.OneToManyChange.createChange(t,e,r,n):"oneToNone"===i?DS.OneToNoneChange.createChange(e,t,r,n):"manyToNone"===i?DS.ManyToNoneChange.createChange(e,t,r,n):"oneToOne"===i?DS.OneToOneChange.createChange(e,t,r,n):"manyToMany"===i?DS.ManyToManyChange.createChange(e,t,r,n):void 0},DS.OneToNoneChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,store:r,changeType:n.changeType,firstRecordName:i,firstRecordKind:"belongsTo"});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.ManyToNoneChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:e,childRecord:t,secondRecord:e,store:r,changeType:n.changeType,secondRecordName:n.key,secondRecordKind:"hasMany"});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.ManyToManyChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"hasMany",secondRecordKind:"hasMany",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.OneToOneChange.createChange=function(e,t,r,n){var i;n.parentType?i=n.parentType.inverseFor(n.key).name:n.key&&(i=n.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"belongsTo",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.OneToOneChange.maintainInvariant=function(e,r,n,i){if("add"===e.changeType&&r.recordIsMaterialized(n)){var a=t(n,i);if(a){var o=DS.OneToOneChange.createChange(n,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(n,i,e.parentRecord,null,o),o.sync()}}},DS.OneToManyChange.createChange=function(e,t,r,n){var i;n.parentType?(i=n.parentType.inverseFor(n.key).name,DS.OneToManyChange.maintainInvariant(n,r,e,i)):n.key&&(i=n.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"hasMany",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,a.getSecondRecordName(),a),a},DS.OneToManyChange.maintainInvariant=function(e,r,n,i){if("add"===e.changeType&&n){var a=t(n,i);if(a){var o=DS.OneToManyChange.createChange(n,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(n,i,e.parentRecord,o.getSecondRecordName(),o),o.sync()}}},DS.RelationshipChange.prototype={getSecondRecordName:function(){var e,t=this.secondRecordName;if(!t){if(e=this.secondRecord,!e)return;var r=this.firstRecord.constructor,n=r.inverseFor(this.firstRecordName);this.secondRecordName=n.name}return this.secondRecordName},getFirstRecordName:function(){var e=this.firstRecordName;return e},destroy:function(){var e=this.childRecord,t=this.getFirstRecordName(),r=this.getSecondRecordName(),n=this.store;n.removeRelationshipChangeFor(e,t,this.parentRecord,r,this.changeType)},getSecondRecord:function(){return this.secondRecord},getFirstRecord:function(){return this.firstRecord},coalesce:function(){var e=this.store.relationshipChangePairsFor(this.firstRecord);n(e,function(e){var t=e.add,r=e.remove;t&&r&&(t.destroy(),r.destroy())})}},DS.RelationshipChangeAdd.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeRemove.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeAdd.prototype.changeType="add",DS.RelationshipChangeAdd.prototype.sync=function(){var n=this.getSecondRecordName(),i=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,n,a)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,n);e(r)&&r.addObject(a)})),a instanceof DS.Model&&o instanceof DS.Model&&t(a,i)!==o&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,i,o)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,i);e(r)&&r.addObject(o)})),this.coalesce()},DS.RelationshipChangeRemove.prototype.changeType="remove",DS.RelationshipChangeRemove.prototype.sync=function(){var n=this.getSecondRecordName(),i=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,n,null)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,n);e(r)&&r.removeObject(a)})),a instanceof DS.Model&&t(a,i)&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,i,null)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,i);e(r)&&r.removeObject(o)})),this.coalesce()}}(),function(){function e(e,n,i){return Ember.computed(function(e,n){var i,a=t(this,"data"),o=t(this,"store");return 2===arguments.length?void 0===n?null:n:(i=a[e],!r(i)&&t(i,"isEmpty")?o.fetchRecord(i):null)}).property("data").meta(i)}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.belongsTo=function(n,i){i=i||{};var a={type:n,isRelationship:!0,options:i,kind:"belongsTo"};return i.async?e(n,i,a):Ember.computed(function(e,i){var a,o,s=t(this,"data"),c=t(this,"store");return o="string"==typeof n?-1===n.indexOf(".")?c.modelFor(n):t(Ember.lookup,n):n,2===arguments.length?void 0===i?null:i:(a=s[e],r(a)?null:(t(a,"isEmpty")&&c.fetchRecord(a),a))}).property("data").meta(a)},DS.Model.reopen({belongsToWillChange:Ember.beforeObserver(function(e,r){if(t(e,"isLoaded")){var n=t(e,r),i=t(e,"store");if(n){var a=DS.RelationshipChange.createChange(e,n,i,{key:r,kind:"belongsTo",changeType:"remove"});a.sync(),this._changesToSync[r]=a}}}),belongsToDidChange:Ember.immediateObserver(function(e,r){if(t(e,"isLoaded")){var n=t(e,r);if(n){var i=t(e,"store"),a=DS.RelationshipChange.createChange(e,n,i,{key:r,kind:"belongsTo",changeType:"add"});a.sync()}}delete this._changesToSync[r]})})}(),function(){function e(e,r,n){return Ember.computed(function(e){var i=Ember.RSVP.defer(),a=t(this,e,r,function(t,r){var a=r.links&&r.links[e];return a?t.findHasMany(this,a,n,i):t.findMany(this,r[e],n.type,i)}),o=i.promise.then(function(){return a});return DS.PromiseArray.create({promise:o})}).property("data").meta(n)}function t(e,t,r,a){var o=e._relationships;if(o[t])return o[t];var s=n(e,"data"),c=n(e,"store"),d=o[t]=a.call(e,c,s);return i(d,{owner:e,name:t,isPolymorphic:r.polymorphic})}function r(r,n){n=n||{};var i={type:r,isRelationship:!0,options:n,kind:"hasMany"};return n.async?e(r,n,i):Ember.computed(function(e){return t(this,e,n,function(t,r){return r[e],t.findMany(this,r[e],i.type)})}).property("data").meta(i)}var n=Ember.get,i=(Ember.set,Ember.setProperties);Ember.EnumerableUtils.forEach,DS.hasMany=function(e,t){return r(e,t)}}(),function(){var e=Ember.get;Ember.set,DS.Model.reopen({didDefineProperty:function(e,t,r){if(r instanceof Ember.Descriptor){var n=r.meta();n.isRelationship&&"belongsTo"===n.kind&&(Ember.addObserver(e,t,null,"belongsToDidChange"),Ember.addBeforeObserver(e,t,null,"belongsToWillChange")),n.parentType=e.constructor}}}),DS.Model.reopenClass({typeForRelationship:function(t){var r=e(this,"relationshipsByName").get(t);return r&&r.type},inverseFor:function(t){function r(t,n,i){i=i||[];var a=e(n,"relationships");if(a){var o=a.get(t);return o&&i.push.apply(i,a.get(t)),t.superclass&&r(t.superclass,n,i),i}}var n=this.typeForRelationship(t);if(!n)return null;var i=this.metaForProperty(t).options;if(null===i.inverse)return null;var a,o;if(i.inverse)a=i.inverse,o=Ember.get(n,"relationshipsByName").get(a).kind;else{var s=r(this,n);if(0===s.length)return null;a=s[0].name,o=s[0].kind}return{type:n,name:a,kind:o}},relationships:Ember.computed(function(){var e=new Ember.MapWithDefault({defaultValue:function(){return[]}});return this.eachComputedProperty(function(t,r){if(r.isRelationship){"string"==typeof r.type&&(r.type=Ember.get(Ember.lookup,r.type));var n=e.get(r.type);n.push({name:t,kind:r.kind})}}),e}),relationshipNames:Ember.computed(function(){var e={hasMany:[],belongsTo:[]};return this.eachComputedProperty(function(t,r){r.isRelationship&&e[r.kind].push(t)}),e}),relatedTypes:Ember.computed(function(){var t,r=Ember.A();return this.eachComputedProperty(function(n,i){i.isRelationship&&(t=i.type,"string"==typeof t&&(t=e(this,t,!1)||e(Ember.lookup,t)),r.contains(t)||r.push(t))}),r}),relationshipsByName:Ember.computed(function(){var e,t=Ember.Map.create();return this.eachComputedProperty(function(r,n){n.isRelationship&&(n.key=r,e=n.type,"string"==typeof e&&(n.type=this.store.modelFor(e)),t.set(r,n))}),t}),fields:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isRelationship?e.set(t,r.kind):r.isAttribute&&e.set(t,"attribute")}),e}),eachRelationship:function(t,r){e(this,"relationshipsByName").forEach(function(e,n){t.call(r,e,n)})},eachRelatedType:function(t,r){e(this,"relatedTypes").forEach(function(e){t.call(r,e)})}}),DS.Model.reopen({eachRelationship:function(e,t){this.constructor.eachRelationship(e,t)}})}(),function(){var e=Ember.get;Ember.set;var t=Ember.run.once,r=Ember.EnumerableUtils.forEach;DS.RecordArrayManager=Ember.Object.extend({init:function(){this.filteredRecordArrays=Ember.MapWithDefault.create({defaultValue:function(){return[]}}),this.changedRecords=[]},recordDidChange:function(e){this.changedRecords.push(e),t(this,this.updateRecordArrays)},recordArraysForRecord:function(e){return e._recordArrays=e._recordArrays||Ember.OrderedSet.create(),e._recordArrays},updateRecordArrays:function(){r(this.changedRecords,function(t){var n,i=t.constructor,a=this.filteredRecordArrays.get(i);r(a,function(r){n=e(r,"filterFunction"),this.updateRecordArray(r,n,i,t)},this);var o=t._loadingRecordArrays;if(o){for(var s=0,c=o.length;c>s;s++)o[s].loadedRecord();t._loadingRecordArrays=[]}},this),this.changedRecords=[]},updateRecordArray:function(e,t,r,n){var i;i=t?t(n):!0;var a=this.recordArraysForRecord(n);i?(a.add(e),e.addRecord(n)):i||(a.remove(e),e.removeRecord(n))},remove:function(e){var t=e._recordArrays;t&&r(t,function(t){t.removeRecord(e)})},updateFilter:function(t,r,n){for(var i,a=this.store.typeMapFor(r),o=a.records,s=0,c=o.length;c>s;s++)i=o[s],e(i,"isDeleted")||e(i,"isEmpty")||this.updateRecordArray(t,n,r,i)},createManyArray:function(e,t){var n=DS.ManyArray.create({type:e,content:t,store:this.store});return r(t,function(e){var t=this.recordArraysForRecord(e);t.add(n)},this),n},registerFilteredRecordArray:function(e,t,r){var n=this.filteredRecordArrays.get(t);n.push(e),this.updateFilter(e,t,r)},registerWaitingRecordArray:function(e,t){var r=e._loadingRecordArrays||[];r.push(t),e._loadingRecordArrays=r}})}(),function(){var e=Ember.get;Ember.set,Ember.merge;var t=Ember.ArrayPolyfills.map;Ember.RSVP.resolve;var r=["description","fileName","lineNumber","message","name","number","stack"];DS.InvalidError=function(e){var t=Error.prototype.constructor.call(this,"The backend rejected the commit because it was invalid: "+Ember.inspect(e));this.errors=e;for(var n=0,i=r.length;i>n;n++)this[r[n]]=t[r[n]]},DS.InvalidError.prototype=Ember.create(Error.prototype),DS.Adapter=Ember.Object.extend(DS._Mappable,{find:Ember.required(Function),findAll:null,findQuery:null,generateIdForRecord:null,serialize:function(t,r){return e(t,"store").serializerFor(t.constructor.typeKey).serialize(t,r)},createRecord:Ember.required(Function),updateRecord:Ember.required(Function),deleteRecord:Ember.required(Function),findMany:function(e,r,n){var i=t.call(n,function(t){return this.find(e,r,t)},this);return Ember.RSVP.all(i)}})}(),function(){var e=Ember.get,t=Ember.String.fmt,r=Ember.EnumerableUtils.indexOf,n=0;DS.FixtureAdapter=DS.Adapter.extend({serializer:null,simulateRemoteResponse:!0,latency:50,fixturesForType:function(e){if(e.FIXTURES){var r=Ember.A(e.FIXTURES);return r.map(function(e){var r=typeof e.id;if("number"!==r&&"string"!==r)throw new Error(t("the id property must be defined as a number or string for fixture %@",[e]));return e.id=e.id+"",e})}return null},queryFixtures:function(){},updateFixtures:function(e,t){e.FIXTURES||(e.FIXTURES=[]);var r=e.FIXTURES;this.deleteLoadedFixture(e,t),r.push(t)},mockJSON:function(e,t,r){return e.serializerFor(t).serialize(r,{includeId:!0})},generateIdForRecord:function(){return n++},find:function(e,t,r){var n,i=this.fixturesForType(t);return i&&(n=Ember.A(i).findProperty("id",r)),n?this.simulateRemoteCall(function(){return n},this):void 0},findMany:function(e,t,n){var i=this.fixturesForType(t);return i&&(i=i.filter(function(e){return-1!==r(n,e.id)})),i?this.simulateRemoteCall(function(){return i},this):void 0},findAll:function(e,t){var r=this.fixturesForType(t);return this.simulateRemoteCall(function(){return r},this)},findQuery:function(e,t,r){var n=this.fixturesForType(t);return n=this.queryFixtures(n,r,t),n?this.simulateRemoteCall(function(){return n},this):void 0},createRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.updateFixtures(t,n),this.simulateRemoteCall(function(){return n},this)},updateRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.updateFixtures(t,n),this.simulateRemoteCall(function(){return n},this)},deleteRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.deleteLoadedFixture(t,n),this.simulateRemoteCall(function(){return null})},deleteLoadedFixture:function(e,t){var n=this.findExistingFixture(e,t);if(n){var i=r(e.FIXTURES,n);return e.FIXTURES.splice(i,1),!0}},findExistingFixture:function(t,r){var n=this.fixturesForType(t),i=e(r,"id");return this.findFixtureById(n,i)},findFixtureById:function(t,r){return Ember.A(t).find(function(t){return""+e(t,"id")==""+r?!0:!1})},simulateRemoteCall:function(t,r){var n=this;return new Ember.RSVP.Promise(function(i){e(n,"simulateRemoteResponse")?Ember.run.later(function(){i(t.call(r))},e(n,"latency")):Ember.run.once(function(){i(t.call(r))})})}})}(),function(){function e(e){return null==e?null:e+""}var t=Ember.get;Ember.set;var r=Ember.ArrayPolyfills.forEach;DS.RESTSerializer=DS.JSONSerializer.extend({normalize:function(e,t,r){return this.normalizeId(t),this.normalizeUsingDeclaredMapping(e,t),this.normalizeAttributes(e,t),this.normalizeRelationships(e,t),this.normalizeHash&&this.normalizeHash[r]?this.normalizeHash[r](t):this._super(e,t,r)},normalizeId:function(e){var r=t(this,"primaryKey");"id"!==r&&(e.id=e[r],delete e[r])},normalizeUsingDeclaredMapping:function(e,r){var n,i,a=t(this,"attrs");if(a)for(i in a)n=a[i],r[i]=r[n],delete r[n]},normalizeAttributes:function(e,t){var r;this.keyForAttribute&&e.eachAttribute(function(e){r=this.keyForAttribute(e),e!==r&&(t[e]=t[r],delete t[r])},this)},normalizeRelationships:function(e,t){var r;this.keyForRelationship&&e.eachRelationship(function(e,n){r=this.keyForRelationship(e,n.kind),e!==r&&(t[e]=t[r],delete t[r])},this)},extractSingle:function(t,n,i,a){var o,s=n.typeKey;for(var c in i)if(c!==s){var d=this.singularize(c),u=t.modelFor(d);r.call(i[c],function(r){r=this.normalize(u,r,c);var n=d===s&&!a&&!o,i=d===s&&e(r.id)===a;n||i?o=r:t.push(d,r)},this)}else o=this.normalize(n,i[c],c);return o},extractArray:function(e,t,r){var n,i=t.typeKey;for(var a in r){var o=this.singularize(a),s=e.modelFor(o),c=o===i,d=r[a].map(function(e){return this.normalize(s,e,a)},this);c?n=d:e.pushMany(o,d)}return n},pluralize:function(e){return Ember.String.pluralize(e)},singularize:function(e){return Ember.String.singularize(e)},serialize:function(){return this._super.apply(this,arguments)}})}(),function(){var e=Ember.get;Ember.set;var t=Ember.ArrayPolyfills.forEach;DS.RESTAdapter=DS.Adapter.extend({defaultSerializer:"_rest",find:function(e,t,r){return this.ajax(this.buildURL(t.typeKey,r),"GET")},findAll:function(e,t,r){var n;return r&&(n={since:r}),this.ajax(this.buildURL(t.typeKey),"GET",{data:n})},findQuery:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:r})},findMany:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:{ids:r}})},findHasMany:function(e,t,r){return this.ajax(r,"GET")},createRecord:function(e,t,r){var n={};return n[t.typeKey]=e.serializerFor(t.typeKey).serialize(r,{includeId:!0}),this.ajax(this.buildURL(t.typeKey),"POST",{data:n})},updateRecord:function(t,r,n){var i={};i[r.typeKey]=t.serializerFor(r.typeKey).serialize(n);var a=e(n,"id");return this.ajax(this.buildURL(r.typeKey,a),"PUT",{data:i})},deleteRecord:function(t,r,n){var i=e(n,"id");return this.ajax(this.buildURL(r.typeKey,i),"DELETE")},buildURL:function(t,r){var n=e(this,"host"),i=e(this,"namespace"),a=[];return n&&a.push(n),i&&a.push(i),a.push(this.rootForType(t)),r&&a.push(r),a=a.join("/"),n||(a="/"+a),a},rootForType:function(e){return Ember.String.pluralize(e)},ajax:function(e,r,n){var i=this;return new Ember.RSVP.Promise(function(a,o){if(n=n||{},n.url=e,n.type=r,n.dataType="json",n.context=i,n.data&&"GET"!==r&&(n.contentType="application/json; charset=utf-8",n.data=JSON.stringify(n.data)),void 0!==i.headers){var s=i.headers;n.beforeSend=function(e){t.call(Ember.keys(s),function(t){e.setRequestHeader(t,s[t])})}}n.success=function(e){Ember.run(null,a,e)},n.error=function(e){e&&(e.then=null),Ember.run(null,o,e)},Ember.$.ajax(n)})}})}(),function(){DS.Model.reopen({_debugInfo:function(){var e=["id"],t={belongsTo:[],hasMany:[]},r=[];this.eachAttribute(function(t){e.push(t)},this),this.eachRelationship(function(e,n){t[n.kind].push(e),r.push(e)});var n=[{name:"Attributes",properties:e,expand:!0},{name:"Belongs To",properties:t.belongsTo,expand:!0},{name:"Has Many",properties:t.hasMany,expand:!0},{name:"Flags",properties:["isLoaded","isDirty","isSaving","isDeleted","isError","isNew","isValid"]}];return{propertyInfo:{includeOtherProperties:!0,groups:n,expensiveProperties:r}}}})}(),function(){Ember.String.pluralize=function(e){return Ember.Inflector.inflector.pluralize(e)},Ember.String.singularize=function(e){return Ember.Inflector.inflector.singularize(e)}}(),function(){function e(e,t){for(var r=0,n=t.length;n>r;r++)e.uncountable[t[r]]=!0}function t(e,t){for(var r,n=0,i=t.length;i>n;n++)r=t[n],e.irregular[r[0]]=r[1],e.irregularInverse[r[1]]=r[0]}function r(r){r=r||{},r.uncountable=r.uncountable||{},r.irregularPairs=r.irregularPairs||{};var n=this.rules={plurals:r.plurals||[],singular:r.singular||[],irregular:{},irregularInverse:{},uncountable:{}};e(n,r.uncountable),t(n,r.irregularPairs)}var n=/^\s*$/;r.prototype={pluralize:function(e){return this.inflect(e,this.rules.plurals)},singularize:function(e){return this.inflect(e,this.rules.singular)},inflect:function(e,t){var r,i,a,o,s,c,d,u,l;if(s=n.test(e))return e;if(o=e.toLowerCase(),c=this.rules.uncountable[o])return e;if(d=this.rules.irregular[o])return d;if(u=this.rules.irregularInverse[o])return u;for(var h=t.length,f=0;h>f&&(r=t[h-1],l=r[0],!l.test(e));h--);return r=r||[],l=r[0],i=r[1],a=e.replace(l,i)}},Ember.Inflector=r}(),function(){Ember.Inflector.defaultRules={plurals:[[/$/,"s"],[/s$/i,"s"],[/^(ax|test)is$/i,"$1es"],[/(octop|vir)us$/i,"$1i"],[/(octop|vir)i$/i,"$1i"],[/(alias|status)$/i,"$1es"],[/(bu)s$/i,"$1ses"],[/(buffal|tomat)o$/i,"$1oes"],[/([ti])um$/i,"$1a"],[/([ti])a$/i,"$1a"],[/sis$/i,"ses"],[/(?:([^f])fe|([lr])f)$/i,"$1$2ves"],[/(hive)$/i,"$1s"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/(x|ch|ss|sh)$/i,"$1es"],[/(matr|vert|ind)(?:ix|ex)$/i,"$1ices"],[/^(m|l)ouse$/i,"$1ice"],[/^(m|l)ice$/i,"$1ice"],[/^(ox)$/i,"$1en"],[/^(oxen)$/i,"$1"],[/(quiz)$/i,"$1zes"]],singular:[[/s$/i,""],[/(ss)$/i,"$1"],[/(n)ews$/i,"$1ews"],[/([ti])a$/i,"$1um"],[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i,"$1sis"],[/(^analy)(sis|ses)$/i,"$1sis"],[/([^f])ves$/i,"$1fe"],[/(hive)s$/i,"$1"],[/(tive)s$/i,"$1"],[/([lr])ves$/i,"$1f"],[/([^aeiouy]|qu)ies$/i,"$1y"],[/(s)eries$/i,"$1eries"],[/(m)ovies$/i,"$1ovie"],[/(x|ch|ss|sh)es$/i,"$1"],[/^(m|l)ice$/i,"$1ouse"],[/(bus)(es)?$/i,"$1"],[/(o)es$/i,"$1"],[/(shoe)s$/i,"$1"],[/(cris|test)(is|es)$/i,"$1is"],[/^(a)x[ie]s$/i,"$1xis"],[/(octop|vir)(us|i)$/i,"$1us"],[/(alias|status)(es)?$/i,"$1"],[/^(ox)en/i,"$1"],[/(vert|ind)ices$/i,"$1ex"],[/(matr)ices$/i,"$1ix"],[/(quiz)zes$/i,"$1"],[/(database)s$/i,"$1"]],irregularPairs:[["person","people"],["man","men"],["child","children"],["sex","sexes"],["move","moves"],["cow","kine"],["zombie","zombies"]],uncountable:["equipment","information","rice","money","species","series","fish","sheep","jeans","police"]}}(),function(){Ember.EXTEND_PROTOTYPES&&(String.prototype.pluralize=function(){return Ember.String.pluralize(this)},String.prototype.singularize=function(){return Ember.String.singularize(this)})}(),function(){Ember.Inflector.inflector=new Ember.Inflector(Ember.Inflector.defaultRules)}()}(),"undefined"==typeof location||"localhost"!==location.hostname&&"127.0.0.1"!==location.hostname||Ember.Logger.warn("You are running a production build of Ember on localhost and won't receive detailed error messages. If you want full error messages please use the non-minified build provided on the Ember website.");
|
14
|
+
// Copyright: Copyright 2011-2013 Tilde Inc. and contributors.
|
15
|
+
// Portions Copyright 2011 LivingSocial Inc.
|
16
|
+
!function(){var e,t;!function(){var r={},n={};e=function(e,t,n){r[e]={deps:t,callback:n}},t=function(e){if(n[e])return n[e];n[e]={};var i,a,o,s,c;if(i=r[e],!i)throw new Error("Module '"+e+"' not found.");a=i.deps,o=i.callback,s=[];for(var u=0,d=a.length;d>u;u++)"exports"===a[u]?s.push(c={}):s.push(t(a[u]));var l=o.apply(this,s);return n[e]=c||l}}(),function(){"undefined"==typeof DS&&(DS=Ember.Namespace.create({VERSION:"1.0.0-beta.2"}),"undefined"!=typeof window&&(window.DS=DS),Ember.libraries&&Ember.libraries.registerCoreLibrary("Ember Data",DS.VERSION))}(),function(){function e(e){return function(){return this[e].apply(this,arguments)}}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.JSONSerializer=Ember.Object.extend({primaryKey:"id",applyTransforms:function(e,t){return e.eachTransformedAttribute(function(e,r){var n=this.transformFor(r);t[e]=n.deserialize(t[e])},this),t},normalize:function(e,t){return t?(this.applyTransforms(e,t),t):t},serialize:function(e,r){var n={};if(r&&r.includeId){var i=t(e,"id");i&&(n[t(this,"primaryKey")]=t(e,"id"))}return e.eachAttribute(function(t,r){this.serializeAttribute(e,n,t,r)},this),e.eachRelationship(function(t,r){"belongsTo"===r.kind?this.serializeBelongsTo(e,n,r):"hasMany"===r.kind&&this.serializeHasMany(e,n,r)},this),n},serializeAttribute:function(e,r,n,i){var a=t(this,"attrs"),o=t(e,n),s=i.type;if(s){var c=this.transformFor(s);o=c.serialize(o)}n=a&&a[n]||(this.keyForAttribute?this.keyForAttribute(n):n),r[n]=o},serializeBelongsTo:function(e,n,i){var a=i.key,o=t(e,a);a=this.keyForRelationship?this.keyForRelationship(a,"belongsTo"):a,n[a]=r(o)?o:t(o,"id"),i.options.polymorphic&&this.serializePolymorphicType(e,n,i)},serializeHasMany:function(e,r,n){var i=n.key,a=DS.RelationshipChange.determineRelationshipType(e.constructor,n);("manyToNone"===a||"manyToMany"===a)&&(r[i]=t(e,i).mapBy("id"))},serializePolymorphicType:Ember.K,extract:function(e,t,r,n,i){this.extractMeta(e,t,r);var a="extract"+i.charAt(0).toUpperCase()+i.substr(1);return this[a](e,t,r,n,i)},extractFindAll:e("extractArray"),extractFindQuery:e("extractArray"),extractFindMany:e("extractArray"),extractFindHasMany:e("extractArray"),extractCreateRecord:e("extractSave"),extractUpdateRecord:e("extractSave"),extractDeleteRecord:e("extractSave"),extractFind:e("extractSingle"),extractFindBelongsTo:e("extractSingle"),extractSave:e("extractSingle"),extractSingle:function(e,t,r){return this.normalize(t,r)},extractArray:function(e,t,r){return this.normalize(t,r)},extractMeta:function(e,t,r){r&&r.meta&&(e.metaForType(t,r.meta),delete r.meta)},transformFor:function(e){var t=this.container.lookup("transform:"+e);return t}})}(),function(){var e=Ember.get,t=Ember.String.capitalize,r=Ember.String.underscore,n=window.DS;n.DebugAdapter=Ember.DataAdapter.extend({getFilters:function(){return[{name:"isNew",desc:"New"},{name:"isModified",desc:"Modified"},{name:"isClean",desc:"Clean"}]},detect:function(e){return e!==n.Model&&n.Model.detect(e)},columnsForType:function(n){var i=[{name:"id",desc:"Id"}],a=0,o=this;return e(n,"attributes").forEach(function(e){if(a++>o.attributeLimit)return!1;var n=t(r(e).replace("_"," "));i.push({name:e,desc:n})}),i},getRecords:function(e){return this.get("store").all(e)},getRecordColumnValues:function(t){var r=this,n=0,i={id:e(t,"id")};return t.eachAttribute(function(a){if(n++>r.attributeLimit)return!1;var o=e(t,a);i[a]=o}),i},getRecordKeywords:function(t){var r=[],n=Ember.A(["id"]);return t.eachAttribute(function(e){n.push(e)}),n.forEach(function(n){r.push(e(t,n))}),r},getRecordFilterValues:function(e){return{isNew:e.get("isNew"),isModified:e.get("isDirty")&&!e.get("isNew"),isClean:!e.get("isDirty")}},getRecordColor:function(e){var t="black";return e.get("isNew")?t="green":e.get("isDirty")&&(t="blue"),t},observeRecord:function(e,t){var r=Ember.A(),n=this,i=Ember.A(["id","isNew","isDirty"]);e.eachAttribute(function(e){i.push(e)}),i.forEach(function(i){var a=function(){t(n.wrapRecord(e))};Ember.addObserver(e,i,a),r.push(function(){Ember.removeObserver(e,i,a)})});var a=function(){r.forEach(function(e){e()})};return a}})}(),function(){DS.Transform=Ember.Object.extend({serialize:Ember.required(),deserialize:Ember.required()})}(),function(){DS.BooleanTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"boolean"===t?e:"string"===t?null!==e.match(/^true$|^t$|^1$/i):"number"===t?1===e:!1},serialize:function(e){return Boolean(e)}})}(),function(){DS.DateTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"string"===t?new Date(Ember.Date.parse(e)):"number"===t?new Date(e):null===e||void 0===e?e:null},serialize:function(e){if(e instanceof Date){var t=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],r=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],n=function(e){return 10>e?"0"+e:""+e},i=e.getUTCFullYear(),a=e.getUTCMonth(),o=e.getUTCDate(),s=e.getUTCDay(),c=e.getUTCHours(),u=e.getUTCMinutes(),d=e.getUTCSeconds(),l=t[s],h=n(o),f=r[a];return l+", "+h+" "+f+" "+i+" "+n(c)+":"+n(u)+":"+n(d)+" GMT"}return null}})}(),function(){var e=Ember.isEmpty;DS.NumberTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:Number(t)},serialize:function(t){return e(t)?null:Number(t)}})}(),function(){var e=Ember.isNone;DS.StringTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:String(t)},serialize:function(t){return e(t)?null:String(t)}})}(),function(){Ember.set,Ember.onLoad("Ember.Application",function(e){e.initializer({name:"store",initialize:function(e,t){t.register("store:main",t.Store||DS.Store),t.register("serializer:_default",DS.JSONSerializer),t.register("serializer:_rest",DS.RESTSerializer),t.register("adapter:_rest",DS.RESTAdapter),e.lookup("store:main")}}),e.initializer({name:"transforms",initialize:function(e,t){t.register("transform:boolean",DS.BooleanTransform),t.register("transform:date",DS.DateTransform),t.register("transform:number",DS.NumberTransform),t.register("transform:string",DS.StringTransform)}}),e.initializer({name:"dataAdapter",initialize:function(e,t){t.register("dataAdapter:main",DS.DebugAdapter)}}),e.initializer({name:"injectStore",initialize:function(e,t){t.inject("controller","store","store:main"),t.inject("route","store","store:main"),t.inject("serializer","store","store:main"),t.inject("dataAdapter","store","store:main")}})})}(),function(){Ember.Date=Ember.Date||{};var e=Date.parse,t=[1,4,5,6,7,10,11];Ember.Date.parse=function(r){var n,i,a=0;if(i=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(r)){for(var o,s=0;o=t[s];++s)i[o]=+i[o]||0;i[2]=(+i[2]||1)-1,i[3]=+i[3]||1,"Z"!==i[8]&&void 0!==i[9]&&(a=60*i[10]+i[11],"+"===i[9]&&(a=0-a)),n=Date.UTC(i[1],i[2],i[3],i[4],i[5]+a,i[6],i[7])}else n=e?e(r):0/0;return n},(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.Date)&&(Date.parse=Ember.Date.parse)}(),function(){var e=Ember.get;Ember.set,DS.RecordArray=Ember.ArrayProxy.extend(Ember.Evented,{type:null,content:null,isLoaded:!1,isUpdating:!1,store:null,objectAtContent:function(t){var r=e(this,"content");return r.objectAt(t)},update:function(){if(!e(this,"isUpdating")){var t=e(this,"store"),r=e(this,"type");t.fetchAll(r,this)}},addRecord:function(t){e(this,"content").addObject(t)},removeRecord:function(t){e(this,"content").removeObject(t)},save:function(){var e=Ember.RSVP.all(this.invoke("save")).then(function(e){return Ember.A(e)});return DS.PromiseArray.create({promise:e})}})}(),function(){var e=Ember.get;DS.FilteredRecordArray=DS.RecordArray.extend({filterFunction:null,isLoaded:!0,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a client-side filter (on "+t+") is immutable.")},updateFilter:Ember.observer(function(){var t=e(this,"manager");t.updateFilter(this,e(this,"type"),e(this,"filterFunction"))},"filterFunction")})}(),function(){var e=Ember.get;Ember.set,DS.AdapterPopulatedRecordArray=DS.RecordArray.extend({query:null,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a server query (on "+t+") is immutable.")},load:function(t){var r=e(this,"store"),n=e(this,"type"),i=r.pushMany(n,t),a=r.metadataFor(n);this.setProperties({content:Ember.A(i),isLoaded:!0,meta:a}),Ember.run.once(this,"trigger","didLoad")}})}(),function(){var e=Ember.get,t=Ember.set,r=Ember.EnumerableUtils.map;DS.ManyArray=DS.RecordArray.extend({init:function(){this._super.apply(this,arguments),this._changesToSync=Ember.OrderedSet.create()},owner:null,isPolymorphic:!1,isLoaded:!1,loadingRecordsCount:function(e){this.loadingRecordsCount=e},loadedRecord:function(){this.loadingRecordsCount--,0===this.loadingRecordsCount&&(t(this,"isLoaded",!0),this.trigger("didLoad"))},fetch:function(){var t=e(this,"content"),r=e(this,"store"),n=e(this,"owner"),i=Ember.RSVP.defer(),a=t.filterProperty("isEmpty",!0);r.fetchMany(a,n,i)},replaceContent:function(e,t,n){n=r(n,function(e){return e},this),this._super(e,t,n)},arrangedContentDidChange:function(){Ember.run.once(this,"fetch")},arrayContentWillChange:function(t,r){var n=e(this,"owner"),i=e(this,"name");if(!n._suspendedRelationships)for(var a=t;t+r>a;a++){var o=e(this,"content").objectAt(a),s=DS.RelationshipChange.createChange(n,o,e(this,"store"),{parentType:n.constructor,changeType:"remove",kind:"hasMany",key:i});this._changesToSync.add(s)}return this._super.apply(this,arguments)},arrayContentDidChange:function(t,r,n){this._super.apply(this,arguments);var i=e(this,"owner"),a=e(this,"name"),o=e(this,"store");if(!i._suspendedRelationships){for(var s=t;t+n>s;s++){var c=e(this,"content").objectAt(s),u=DS.RelationshipChange.createChange(i,c,o,{parentType:i.constructor,changeType:"add",kind:"hasMany",key:a});u.hasManyName=a,this._changesToSync.add(u)}this._changesToSync.forEach(function(e){e.sync()}),this._changesToSync.clear()}},createRecord:function(t){var r,n=e(this,"owner"),i=e(n,"store"),a=e(this,"type");return r=i.createRecord.call(i,a,t),this.pushObject(r),r}})}(),function(){function e(e){var t=Ember.meta(e,!0),r="DS.Mappable",n=t[r];return n||(t[r]={}),t.hasOwnProperty(r)||(t[r]=Ember.create(t[r])),t[r]}Ember.get;var t=Ember.ArrayPolyfills.forEach,r=function(e){return e},n=function(e){return e},i=function(e,t){return t};DS._Mappable=Ember.Mixin.create({createInstanceMapFor:function(t){var r=e(this);if(r.values=r.values||{},r.values[t])return r.values[t];for(var n=r.values[t]=new Ember.Map,i=this.constructor;i&&i!==DS.Store;)this._copyMap(t,i,n),i=i.superclass;return r.values[t]=n,n},_copyMap:function(a,o,s){function c(e,t){var a=(o.transformMapKey||n)(e,t),c=(o.transformMapValue||i)(e,t),u=s.get(a),d=c;u&&(d=(this.constructor.resolveMapConflict||r)(u,d)),s.set(a,d)}var u=e(o),d=u[a];d&&t.call(d,c,this)}}),DS._Mappable.generateMapFunctionFor=function(t,r){return function(n,i){var a=e(this),o=a[t]||Ember.MapWithDefault.create({defaultValue:function(){return{}}});r.call(this,n,i,o),a[t]=o}}}(),function(){function e(e,r,a,o){return r.eachRelationship(function(r,s){if(a.links&&a.links[r])return o&&s.options.async&&(o._relationships[r]=null),void 0;var c=s.kind,u=a[r];null!=u&&("belongsTo"===c?t(e,a,r,s,u):"hasMany"===c&&(n(e,a,r,s,u),i(o,r,u)))}),a}function t(e,t,n,i,a){if(!(v(a)||a instanceof DS.Model)){var o;"number"==typeof a||"string"==typeof a?(o=r(i,n,t),t[n]=e.recordForId(o,a)):"object"==typeof a&&(t[n]=e.recordForId(a.type,a.id))}}function r(e,t,r){return e.options.polymorphic?r[t+"Type"]:e.type}function n(e,r,n,i,a){for(var o=0,s=a.length;s>o;o++)t(e,a,o,i,a[o])}function i(e,t,r){e&&r.pushObjects(e.get(t).filterBy("isNew"))}function a(e){return DS.PromiseObject.create({promise:e})}function o(e){return DS.PromiseArray.create({promise:e})}function s(e,t,r){return e.lookup("serializer:"+t)||e.lookup("serializer:application")||e.lookup("serializer:"+r)||e.lookup("serializer:_default")}function c(e,t){var r=e.serializer,n=e.defaultSerializer,i=e.container;return i&&void 0===r&&(r=s(i,t.typeKey,n)),(null===r||void 0===r)&&(r={extract:function(e,t,r){return r}}),r}function u(e,t,r,n,i){var a=e.find(t,r,n),o=c(e,r);return D(a).then(function(e){return e=o.extract(t,r,e,n,"find"),t.push(r,e)},function(e){var i=t.getById(r,n);throw i.notFound(),e}).then(i.resolve,i.reject)}function d(e,t,r,n,i,a){var o=e.findMany(t,r,n,i),s=c(e,r);return D(o).then(function(e){e=s.extract(t,r,e,null,"findMany"),t.pushMany(r,e)}).then(a.resolve,a.reject)}function l(e,t,r,n,i,a){var o=e.findHasMany(t,r,n,i),s=c(e,i.type);return D(o).then(function(e){e=s.extract(t,i.type,e,null,"findHasMany");var n=t.pushMany(i.type,e);r.updateHasMany(i.key,n)}).then(a.resolve,a.reject)}function h(e,t,r,n,i,a){var o=e.findBelongsTo(t,r,n,i),s=c(e,i.type);return D(o).then(function(e){e=s.extract(t,i.type,e,null,"findBelongsTo");var r=t.push(i.type,e);return r.updateBelongsTo(i.key,r),r}).then(a.resolve,a.reject)}function f(e,t,r,n,i){var a=e.findAll(t,r,n),o=c(e,r);return D(a).then(function(e){return e=o.extract(t,r,e,null,"findAll"),t.pushMany(r,e),t.didUpdateAll(r),t.all(r)}).then(i.resolve,i.reject)}function p(e,t,r,n,i,a){var o=e.findQuery(t,r,n,i),s=c(e,r);return D(o).then(function(e){return e=s.extract(t,r,e,null,"findAll"),i.load(e),i}).then(a.resolve,a.reject)}function m(e,t,r,n,i){var a=n.constructor,o=e[r](t,a,n),s=c(e,a);return o.then(function(e){return e&&(e=s.extract(t,a,e,y(n,"id"),r)),t.didSaveRecord(n,e),n},function(e){throw e instanceof DS.InvalidError?t.recordWasInvalid(n,e.errors):t.recordWasError(n,e),e}).then(i.resolve,i.reject)}var y=Ember.get,g=Ember.set,b=Ember.run.once,v=Ember.isNone,R=Ember.EnumerableUtils.forEach,E=Ember.EnumerableUtils.indexOf,S=Ember.EnumerableUtils.map,D=Ember.RSVP.resolve,T=function(e){return null==e?null:e+""};DS.Store=Ember.Object.extend(DS._Mappable,{init:function(){this.typeMaps={},this.recordArrayManager=DS.RecordArrayManager.create({store:this}),this._relationshipChanges={},this._pendingSave=[]},adapter:"_rest",serialize:function(e,t){return this.serializerFor(e.constructor.typeKey).serialize(e,t)},defaultAdapter:Ember.computed(function(){var e=y(this,"adapter");return"string"==typeof e&&(e=this.container.lookup("adapter:"+e)||this.container.lookup("adapter:application")||this.container.lookup("adapter:_rest")),DS.Adapter.detect(e)&&(e=e.create({container:this.container})),e}).property("adapter"),createRecord:function(e,t){e=this.modelFor(e),t=t||{},v(t.id)&&(t.id=this._generateId(e)),t.id=T(t.id);var r=this.buildRecord(e,t.id);return r.loadedData(),r.setProperties(t),r},_generateId:function(e){var t=this.adapterFor(e);return t&&t.generateIdForRecord?t.generateIdForRecord(this):null},deleteRecord:function(e){e.deleteRecord()},unloadRecord:function(e){e.unloadRecord()},find:function(e,t){return void 0===t?this.findAll(e):"object"===Ember.typeOf(t)?this.findQuery(e,t):this.findById(e,T(t))},findById:function(e,t){e=this.modelFor(e);var r=this.recordForId(e,t),n=this.fetchRecord(r)||D(r);return a(n)},findByIds:function(e,t){var r=this;return o(Ember.RSVP.all(S(t,function(t){return r.findById(e,t)})).then(function(e){return Ember.A(e)}))},fetchRecord:function(e){if(v(e))return null;if(e._loadingPromise)return e._loadingPromise;if(!y(e,"isEmpty"))return null;var t=e.constructor,r=y(e,"id"),n=Ember.RSVP.defer();e.loadingData(n.promise);var i=this.adapterFor(t);return u(i,this,t,r,n),n.promise},getById:function(e,t){return e=this.modelFor(e),this.hasRecordForId(e,t)?this.recordForId(e,t):null},reloadRecord:function(e,t){var r=e.constructor,n=this.adapterFor(r),i=y(e,"id");return u(n,this,r,i,t)},fetchMany:function(e,t,r){if(e.length){var n=Ember.MapWithDefault.create({defaultValue:function(){return Ember.A()}});R(e,function(e){n.get(e.constructor).push(e)}),R(n,function(e,n){var i=n.mapProperty("id"),a=this.adapterFor(e);d(a,this,e,i,t,r)},this)}},hasRecordForId:function(e,t){return t=T(t),!!this.typeMapFor(e).idToRecord[t]},recordForId:function(e,t){e=this.modelFor(e),t=T(t);var r=this.typeMapFor(e).idToRecord[t];return r||(r=this.buildRecord(e,t)),r},findMany:function(e,t,r,n){r=this.modelFor(r),t=Ember.A(t);var i=t.filterProperty("isEmpty",!0),a=this.recordArrayManager.createManyArray(r,t);return R(i,function(e){e.loadingData()}),a.loadingRecordsCount=i.length,i.length?(R(i,function(e){this.recordArrayManager.registerWaitingRecordArray(e,a)},this),this.fetchMany(i,e,n)):(n&&n.resolve(),a.set("isLoaded",!0),Ember.run.once(a,"trigger","didLoad")),a},findHasMany:function(e,t,r,n){var i=this.adapterFor(e.constructor),a=this.recordArrayManager.createManyArray(r.type,Ember.A([]));return l(i,this,e,t,r,n),a},findBelongsTo:function(e,t,r,n){var i=this.adapterFor(e.constructor);h(i,this,e,t,r,n)},findQuery:function(e,t){e=this.modelFor(e);var r=DS.AdapterPopulatedRecordArray.create({type:e,query:t,content:Ember.A(),store:this}),n=this.adapterFor(e),i=Ember.RSVP.defer();return p(n,this,e,t,r,i),o(i.promise)},findAll:function(e){return e=this.modelFor(e),this.fetchAll(e,this.all(e))},fetchAll:function(e,t){var r=this.adapterFor(e),n=this.typeMapFor(e).metadata.since,i=Ember.RSVP.defer();return g(t,"isUpdating",!0),f(r,this,e,n,i),o(i.promise)},didUpdateAll:function(e){var t=this.typeMapFor(e).findAllCache;g(t,"isUpdating",!1)},all:function(e){e=this.modelFor(e);var t=this.typeMapFor(e),r=t.findAllCache;if(r)return r;var n=DS.RecordArray.create({type:e,content:Ember.A(),store:this,isLoaded:!0});return this.recordArrayManager.registerFilteredRecordArray(n,e),t.findAllCache=n,n},unloadAll:function(e){e=this.modelFor(e);for(var t,r=this.typeMapFor(e),n=r.records;t=n.pop();)t.unloadRecord()},filter:function(e,t,r){var n;3===arguments.length?n=this.findQuery(e,t):2===arguments.length&&(r=t),e=this.modelFor(e);var i=DS.FilteredRecordArray.create({type:e,content:Ember.A(),store:this,manager:this.recordArrayManager,filterFunction:r});return this.recordArrayManager.registerFilteredRecordArray(i,e,r),n?n.then(function(){return i}):i},recordIsLoaded:function(e,t){return this.hasRecordForId(e,t)?!y(this.recordForId(e,t),"isEmpty"):!1},metadataFor:function(e){return e=this.modelFor(e),this.typeMapFor(e).metadata},dataWasUpdated:function(e,t){y(t,"isDeleted")||y(t,"isLoaded")&&this.recordArrayManager.recordDidChange(t)},scheduleSave:function(e,t){e.adapterWillCommit(),this._pendingSave.push([e,t]),b(this,"flushPendingSave")},flushPendingSave:function(){var e=this._pendingSave.slice();this._pendingSave=[],R(e,function(e){var t,r=e[0],n=e[1],i=this.adapterFor(r.constructor);t=y(r,"isNew")?"createRecord":y(r,"isDeleted")?"deleteRecord":"updateRecord",m(i,this,t,r,n)},this)},didSaveRecord:function(t,r){r&&(r=e(this,t.constructor,r,t),this.updateId(t,r)),t.adapterDidCommit(r)},recordWasInvalid:function(e,t){e.adapterDidInvalidate(t)},recordWasError:function(e){e.adapterDidError()},updateId:function(e,t){var r=(y(e,"id"),T(t.id));this.typeMapFor(e.constructor).idToRecord[r]=e,g(e,"id",r)},typeMapFor:function(e){var t,r=y(this,"typeMaps"),n=Ember.guidFor(e);return(t=r[n])?t:(t={idToRecord:{},records:[],metadata:{}},r[n]=t,t)},_load:function(e,t,r){var n=T(t.id),i=this.recordForId(e,n);return i.setupData(t,r),this.recordArrayManager.recordDidChange(i),i},modelFor:function(e){var t;return"string"==typeof e?(t=this.container.lookupFactory("model:"+e),t.typeKey=e):t=e,t.store=this,t},push:function(t,r,n){return t=this.modelFor(t),r=e(this,t,r),this._load(t,r,n),this.recordForId(t,r.id)},pushPayload:function(e,t){var r=this.serializerFor(e);r.pushPayload(this,t)},update:function(e,t){return this.push(e,t,!0)},pushMany:function(e,t){return S(t,function(t){return this.push(e,t)},this)},metaForType:function(e,t){e=this.modelFor(e),Ember.merge(this.typeMapFor(e).metadata,t)},buildRecord:function(e,t,r){var n=this.typeMapFor(e),i=n.idToRecord,a=e._create({id:t,store:this,container:this.container});return r&&a.setupData(r),t&&(i[t]=a),n.records.push(a),a},dematerializeRecord:function(e){var t=e.constructor,r=this.typeMapFor(t),n=y(e,"id");e.updateRecordArrays(),n&&delete r.idToRecord[n];var i=E(r.records,e);r.records.splice(i,1)},addRelationshipChangeFor:function(e,t,r,n,i){var a=e.clientId,o=r?r:r,s=t+n,c=this._relationshipChanges;a in c||(c[a]={}),o in c[a]||(c[a][o]={}),s in c[a][o]||(c[a][o][s]={}),c[a][o][s][i.changeType]=i},removeRelationshipChangeFor:function(e,t,r,n,i){var a=e.clientId,o=r?r.clientId:r,s=this._relationshipChanges,c=t+n;a in s&&o in s[a]&&c in s[a][o]&&delete s[a][o][c][i]},relationshipChangePairsFor:function(e){var t=[];if(!e)return t;var r=this._relationshipChanges[e.clientId];for(var n in r)if(r.hasOwnProperty(n))for(var i in r[n])r[n].hasOwnProperty(i)&&t.push(r[n][i]);return t},adapterFor:function(e){var t,r=this.container;return r&&(t=r.lookup("adapter:"+e.typeKey)||r.lookup("adapter:application")),t||y(this,"defaultAdapter")},serializerFor:function(e){e=this.modelFor(e);var t=this.adapterFor(e);return s(this.container,e.typeKey,t&&t.defaultSerializer)}}),DS.PromiseArray=Ember.ArrayProxy.extend(Ember.PromiseProxyMixin),DS.PromiseObject=Ember.ObjectProxy.extend(Ember.PromiseProxyMixin)}(),function(){function e(t){var r,n={};for(var i in t)r=t[i],n[i]=r&&"object"==typeof r?e(r):r;return n}function t(e,t){for(var r in t)e[r]=t[r];return e}function r(r){var n=e(c);return t(n,r)}function n(e,r,i){e=t(r?Ember.create(r):{},e),e.parentState=r,e.stateName=i;for(var a in e)e.hasOwnProperty(a)&&"parentState"!==a&&"stateName"!==a&&"object"==typeof e[a]&&(e[a]=n(e[a],e,i+"."+a));return e}var i=Ember.get,a=Ember.set,o=function(e){var t,r,n,i=Ember.keys(e);for(t=0,r=i.length;r>t;t++)if(n=i[t],e.hasOwnProperty(n)&&e[n])return!0;return!1},s=function(e,t){t.value===t.originalValue?(delete e._attributes[t.name],e.send("propertyWasReset",t.name)):t.value!==t.oldValue&&e.send("becomeDirty"),e.updateRecordArraysLater()},c={initialState:"uncommitted",isDirty:!0,uncommitted:{didSetProperty:s,propertyWasReset:function(e){var t=!1;for(var r in e._attributes){t=!0;break}t||e.send("rolledBack")},pushedData:Ember.K,becomeDirty:Ember.K,willCommit:function(e){e.transitionTo("inFlight")},reloadRecord:function(e,t){i(e,"store").reloadRecord(e,t)},rolledBack:function(e){e.transitionTo("loaded.saved")},becameInvalid:function(e){e.transitionTo("invalid")},rollback:function(e){e.rollback()}},inFlight:{isSaving:!0,didSetProperty:s,becomeDirty:Ember.K,pushedData:Ember.K,willCommit:Ember.K,didCommit:function(e){var t=i(this,"dirtyType");e.transitionTo("saved"),e.send("invokeLifecycleCallbacks",t)},becameInvalid:function(e,t){a(e,"errors",t),e.transitionTo("invalid"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},invalid:{isValid:!1,deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},didSetProperty:function(e,t){var r=i(e,"errors"),n=t.name;a(r,n,null),o(r)||e.send("becameValid"),s(e,t)},becomeDirty:Ember.K,rollback:function(e){e.send("becameValid"),e.send("rollback")},becameValid:function(e){e.transitionTo("uncommitted")},invokeLifecycleCallbacks:function(e){e.triggerLater("becameInvalid",e)}}},u=r({dirtyType:"created",isNew:!0});u.uncommitted.rolledBack=function(e){e.transitionTo("deleted.saved")};var d=r({dirtyType:"updated"});u.uncommitted.deleteRecord=function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},u.uncommitted.rollback=function(e){c.uncommitted.rollback.apply(this,arguments),e.transitionTo("deleted.saved")},d.uncommitted.deleteRecord=function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()};var l={isEmpty:!1,isLoading:!1,isLoaded:!1,isDirty:!1,isSaving:!1,isDeleted:!1,isNew:!1,isValid:!0,rolledBack:Ember.K,propertyWasReset:Ember.K,empty:{isEmpty:!0,loadingData:function(e,t){e._loadingPromise=t,e.transitionTo("loading")},loadedData:function(e){e.transitionTo("loaded.created.uncommitted"),e.suspendRelationshipObservers(function(){e.notifyPropertyChange("data")})},pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad")}},loading:{isLoading:!0,exit:function(e){e._loadingPromise=null},pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad"),a(e,"isError",!1)},becameError:function(e){e.triggerLater("becameError",e)},notFound:function(e){e.transitionTo("empty")}},loaded:{initialState:"saved",isLoaded:!0,saved:{setup:function(e){var t=e._attributes,r=!1;for(var n in t)if(t.hasOwnProperty(n)){r=!0;break}r&&e.adapterDidDirty()},didSetProperty:s,pushedData:Ember.K,becomeDirty:function(e){e.transitionTo("updated.uncommitted")},willCommit:function(e){e.transitionTo("updated.inFlight")},reloadRecord:function(e,t){i(e,"store").reloadRecord(e,t)},deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},unloadRecord:function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},didCommit:function(e){e.send("invokeLifecycleCallbacks",i(e,"lastDirtyType"))}},created:u,updated:d},deleted:{initialState:"uncommitted",dirtyType:"deleted",isDeleted:!0,isLoaded:!0,isDirty:!0,setup:function(e){var t=i(e,"store");t.recordArrayManager.remove(e)},uncommitted:{willCommit:function(e){e.transitionTo("inFlight")},rollback:function(e){e.rollback()},becomeDirty:Ember.K,deleteRecord:Ember.K,rolledBack:function(e){e.transitionTo("loaded.saved")}},inFlight:{isSaving:!0,willCommit:Ember.K,didCommit:function(e){e.transitionTo("saved"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},saved:{isDirty:!1,setup:function(e){var t=i(e,"store");t.dematerializeRecord(e)},invokeLifecycleCallbacks:function(e){e.triggerLater("didDelete",e),e.triggerLater("didCommit",e)}}},invokeLifecycleCallbacks:function(e,t){"created"===t?e.triggerLater("didCreate",e):e.triggerLater("didUpdate",e),e.triggerLater("didCommit",e)}};l=n(l,null,"root"),DS.RootState=l}(),function(){var e=Ember.get,t=Ember.set,r=Ember.merge,n=Ember.run.once,i=Ember.computed(function(t){return e(e(this,"currentState"),t)}).property("currentState").readOnly();DS.Model=Ember.Object.extend(Ember.Evented,{isEmpty:i,isLoading:i,isLoaded:i,isDirty:i,isSaving:i,isDeleted:i,isNew:i,isValid:i,dirtyType:i,isError:!1,isReloading:!1,clientId:null,id:null,transaction:null,currentState:null,errors:null,serialize:function(t){var r=e(this,"store");return r.serialize(this,t)},toJSON:function(e){var t=DS.JSONSerializer.create({container:this.container});return t.serialize(this,e)},didLoad:Ember.K,didReload:Ember.K,didUpdate:Ember.K,didCreate:Ember.K,didDelete:Ember.K,becameInvalid:Ember.K,becameError:Ember.K,data:Ember.computed(function(){return this._data=this._data||{},this._data}).property(),_data:null,init:function(){t(this,"currentState",DS.RootState.empty),this._super(),this._setup()},_setup:function(){this._changesToSync={},this._deferredTriggers=[],this._data={},this._attributes={},this._inFlightAttributes={},this._relationships={}},send:function(t,r){var n=e(this,"currentState");return n[t]||this._unhandledEvent(n,t,r),n[t](this,r)},transitionTo:function(r){var n=r.split(".",1),i=e(this,"currentState"),a=i;do a.exit&&a.exit(this),a=a.parentState;while(!a.hasOwnProperty(n));var o,s,c=r.split("."),u=[],d=[];for(o=0,s=c.length;s>o;o++)a=a[c[o]],a.enter&&d.push(a),a.setup&&u.push(a);for(o=0,s=d.length;s>o;o++)d[o].enter(this);for(t(this,"currentState",a),o=0,s=u.length;s>o;o++)u[o].setup(this);this.updateRecordArraysLater()},_unhandledEvent:function(e,t,r){var n="Attempted to handle event `"+t+"` ";throw n+="on "+String(this)+" while in state ",n+=e.stateName+". ",void 0!==r&&(n+="Called with "+Ember.inspect(r)+"."),new Ember.Error(n)},withTransaction:function(t){var r=e(this,"transaction");r&&t(r)},loadingData:function(e){this.send("loadingData",e)},loadedData:function(){this.send("loadedData")},notFound:function(){this.send("notFound")},pushedData:function(){this.send("pushedData")},deleteRecord:function(){this.send("deleteRecord")},destroyRecord:function(){return this.deleteRecord(),this.save()},unloadRecord:function(){this.send("unloadRecord")},clearRelationships:function(){this.eachRelationship(function(e,r){if("belongsTo"===r.kind)t(this,e,null);else if("hasMany"===r.kind){var n=this._relationships[r.name];n&&n.clear()}},this)},updateRecordArrays:function(){var t=e(this,"store");t&&t.dataWasUpdated(this.constructor,this)},changedAttributes:function(){var t,r=e(this,"_data"),n=e(this,"_attributes"),i={};for(t in n)i[t]=[r[t],n[t]];return i},adapterWillCommit:function(){this.send("willCommit")},adapterDidCommit:function(e){t(this,"isError",!1),e?this._data=e:Ember.mixin(this._data,this._inFlightAttributes),this._inFlightAttributes={},this.send("didCommit"),this.updateRecordArraysLater(),e&&this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},adapterDidDirty:function(){this.send("becomeDirty"),this.updateRecordArraysLater()},dataDidChange:Ember.observer(function(){this.reloadHasManys()},"data"),reloadHasManys:function(){var t=e(this.constructor,"relationshipsByName");this.updateRecordArraysLater(),t.forEach(function(e,t){this._data.links&&this._data.links[e]||"hasMany"===t.kind&&this.hasManyDidChange(t.key)},this)},hasManyDidChange:function(e){var r=this._relationships[e];if(r){var n=this._data[e]||[];t(r,"content",Ember.A(n)),t(r,"isLoaded",!0),r.trigger("didLoad")}},updateRecordArraysLater:function(){Ember.run.once(this,this.updateRecordArrays)},setupData:function(e,t){t?Ember.merge(this._data,e):this._data=e;var r=this._relationships;this.eachRelationship(function(t,n){e.links&&e.links[t]||n.options.async&&(r[t]=null)}),e&&this.pushedData(),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},materializeId:function(e){t(this,"id",e)},materializeAttributes:function(e){r(this._data,e)},materializeAttribute:function(e,t){this._data[e]=t},updateHasMany:function(e,t){this._data[e]=t,this.hasManyDidChange(e)},updateBelongsTo:function(e,t){this._data[e]=t},rollback:function(){this._attributes={},e(this,"isError")&&(this._inFlightAttributes={},t(this,"isError",!1)),this.send("rolledBack"),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},toStringExtension:function(){return e(this,"id")},suspendRelationshipObservers:function(t,r){var n=e(this.constructor,"relationshipNames").belongsTo,i=this;try{this._suspendedRelationships=!0,Ember._suspendObservers(i,n,null,"belongsToDidChange",function(){Ember._suspendBeforeObservers(i,n,null,"belongsToWillChange",function(){t.call(r||i)})})}finally{this._suspendedRelationships=!1}},save:function(){var e=Ember.RSVP.defer();return this.get("store").scheduleSave(this,e),this._inFlightAttributes=this._attributes,this._attributes={},DS.PromiseObject.create({promise:e.promise})},reload:function(){t(this,"isReloading",!0);var e=Ember.RSVP.defer(),r=this;return e.promise=e.promise.then(function(){return r.set("isReloading",!1),r.set("isError",!1),r},function(e){throw r.set("isError",!0),e}),this.send("reloadRecord",e),DS.PromiseObject.create({promise:e.promise})},adapterDidUpdateAttribute:function(e,t){void 0!==t?(this._data[e]=t,this.notifyPropertyChange(e)):this._data[e]=this._inFlightAttributes[e],this.updateRecordArraysLater()},adapterDidInvalidate:function(e){this.send("becameInvalid",e)},adapterDidError:function(){this.send("becameError"),t(this,"isError",!0)},trigger:function(e){Ember.tryInvoke(this,e,[].slice.call(arguments,1)),this._super.apply(this,arguments)},triggerLater:function(){this._deferredTriggers.push(arguments),n(this,"_triggerDeferredTriggers")},_triggerDeferredTriggers:function(){for(var e=0,t=this._deferredTriggers.length;t>e;e++)this.trigger.apply(this,this._deferredTriggers[e]);this._deferredTriggers=[]}}),DS.Model.reopenClass({_create:DS.Model.create,create:function(){throw new Ember.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.")}})}(),function(){function e(e,t){return"function"==typeof t.defaultValue?t.defaultValue():t.defaultValue}function t(e,t){return e._attributes.hasOwnProperty(t)||e._inFlightAttributes.hasOwnProperty(t)||e._data.hasOwnProperty(t)}function r(e,t){return e._attributes.hasOwnProperty(t)?e._attributes[t]:e._inFlightAttributes.hasOwnProperty(t)?e._inFlightAttributes[t]:e._data[t]}var n=Ember.get;DS.Model.reopenClass({attributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isAttribute&&(r.name=t,e.set(t,r))}),e}),transformedAttributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachAttribute(function(t,r){r.type&&e.set(t,r.type)}),e}),eachAttribute:function(e,t){n(this,"attributes").forEach(function(r,n){e.call(t,r,n)},t)},eachTransformedAttribute:function(e,t){n(this,"transformedAttributes").forEach(function(r,n){e.call(t,r,n)
|
17
|
+
})}}),DS.Model.reopen({eachAttribute:function(e,t){this.constructor.eachAttribute(e,t)}}),DS.attr=function(n,i){i=i||{};var a={type:n,isAttribute:!0,options:i};return Ember.computed(function(n,a){if(arguments.length>1){var o=this._attributes[n]||this._inFlightAttributes[n]||this._data[n];return this.send("didSetProperty",{name:n,oldValue:o,originalValue:this._data[n],value:a}),this._attributes[n]=a,a}return t(this,n)?r(this,n):e(this,i,n)}).property("data").meta(a)}}(),function(){var e=DS.AttributeChange=function(e){this.record=e.record,this.store=e.store,this.name=e.name,this.value=e.value,this.oldValue=e.oldValue};e.createChange=function(t){return new e(t)},e.prototype={sync:function(){this.value!==this.oldValue&&(this.record.send("becomeDirty"),this.record.updateRecordArraysLater()),this.destroy()},destroy:function(){delete this.record._changesToSync[this.name]}}}(),function(){function e(e){return"object"==typeof e&&(!e.then||"function"!=typeof e.then)}var t=Ember.get,r=Ember.set,n=Ember.EnumerableUtils.forEach;DS.RelationshipChange=function(e){this.parentRecord=e.parentRecord,this.childRecord=e.childRecord,this.firstRecord=e.firstRecord,this.firstRecordKind=e.firstRecordKind,this.firstRecordName=e.firstRecordName,this.secondRecord=e.secondRecord,this.secondRecordKind=e.secondRecordKind,this.secondRecordName=e.secondRecordName,this.changeType=e.changeType,this.store=e.store,this.committed={}},DS.RelationshipChangeAdd=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChangeRemove=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChange.create=function(e){return new DS.RelationshipChange(e)},DS.RelationshipChangeAdd.create=function(e){return new DS.RelationshipChangeAdd(e)},DS.RelationshipChangeRemove.create=function(e){return new DS.RelationshipChangeRemove(e)},DS.OneToManyChange={},DS.OneToNoneChange={},DS.ManyToNoneChange={},DS.OneToOneChange={},DS.ManyToManyChange={},DS.RelationshipChange._createChange=function(e){return"add"===e.changeType?DS.RelationshipChangeAdd.create(e):"remove"===e.changeType?DS.RelationshipChangeRemove.create(e):void 0},DS.RelationshipChange.determineRelationshipType=function(e,t){var r,n,i=t.key,a=t.kind,o=e.inverseFor(i);return o&&(r=o.name,n=o.kind),o?"belongsTo"===n?"belongsTo"===a?"oneToOne":"manyToOne":"belongsTo"===a?"oneToMany":"manyToMany":"belongsTo"===a?"oneToNone":"manyToNone"},DS.RelationshipChange.createChange=function(e,t,r,n){var i,a=e.constructor;return i=DS.RelationshipChange.determineRelationshipType(a,n),"oneToMany"===i?DS.OneToManyChange.createChange(e,t,r,n):"manyToOne"===i?DS.OneToManyChange.createChange(t,e,r,n):"oneToNone"===i?DS.OneToNoneChange.createChange(e,t,r,n):"manyToNone"===i?DS.ManyToNoneChange.createChange(e,t,r,n):"oneToOne"===i?DS.OneToOneChange.createChange(e,t,r,n):"manyToMany"===i?DS.ManyToManyChange.createChange(e,t,r,n):void 0},DS.OneToNoneChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,store:r,changeType:n.changeType,firstRecordName:i,firstRecordKind:"belongsTo"});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.ManyToNoneChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:e,childRecord:t,secondRecord:e,store:r,changeType:n.changeType,secondRecordName:n.key,secondRecordKind:"hasMany"});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.ManyToManyChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"hasMany",secondRecordKind:"hasMany",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.OneToOneChange.createChange=function(e,t,r,n){var i;n.parentType?i=n.parentType.inverseFor(n.key).name:n.key&&(i=n.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"belongsTo",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.OneToOneChange.maintainInvariant=function(e,r,n,i){if("add"===e.changeType&&r.recordIsMaterialized(n)){var a=t(n,i);if(a){var o=DS.OneToOneChange.createChange(n,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(n,i,e.parentRecord,null,o),o.sync()}}},DS.OneToManyChange.createChange=function(e,t,r,n){var i;n.parentType?(i=n.parentType.inverseFor(n.key).name,DS.OneToManyChange.maintainInvariant(n,r,e,i)):n.key&&(i=n.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"hasMany",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,a.getSecondRecordName(),a),a},DS.OneToManyChange.maintainInvariant=function(e,r,n,i){if("add"===e.changeType&&n){var a=t(n,i);if(a){var o=DS.OneToManyChange.createChange(n,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(n,i,e.parentRecord,o.getSecondRecordName(),o),o.sync()}}},DS.RelationshipChange.prototype={getSecondRecordName:function(){var e,t=this.secondRecordName;if(!t){if(e=this.secondRecord,!e)return;var r=this.firstRecord.constructor,n=r.inverseFor(this.firstRecordName);this.secondRecordName=n.name}return this.secondRecordName},getFirstRecordName:function(){var e=this.firstRecordName;return e},destroy:function(){var e=this.childRecord,t=this.getFirstRecordName(),r=this.getSecondRecordName(),n=this.store;n.removeRelationshipChangeFor(e,t,this.parentRecord,r,this.changeType)},getSecondRecord:function(){return this.secondRecord},getFirstRecord:function(){return this.firstRecord},coalesce:function(){var e=this.store.relationshipChangePairsFor(this.firstRecord);n(e,function(e){var t=e.add,r=e.remove;t&&r&&(t.destroy(),r.destroy())})}},DS.RelationshipChangeAdd.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeRemove.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeAdd.prototype.changeType="add",DS.RelationshipChangeAdd.prototype.sync=function(){var n=this.getSecondRecordName(),i=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,n,a)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,n);e(r)&&r.addObject(a)})),a instanceof DS.Model&&o instanceof DS.Model&&t(a,i)!==o&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,i,o)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,i);e(r)&&r.addObject(o)})),this.coalesce()},DS.RelationshipChangeRemove.prototype.changeType="remove",DS.RelationshipChangeRemove.prototype.sync=function(){var n=this.getSecondRecordName(),i=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,n,null)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,n);e(r)&&r.removeObject(a)})),a instanceof DS.Model&&t(a,i)&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,i,null)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,i);e(r)&&r.removeObject(o)})),this.coalesce()}}(),function(){function e(e,n,i){return Ember.computed(function(e,n){var a=t(this,"data"),o=t(this,"store");if(2===arguments.length)return void 0===n?null:DS.PromiseObject.create({promise:Ember.RSVP.resolve(n)});var s=a.links&&a.links[e],c=a[e];if(r(c)){if(s){var u=Ember.RSVP.defer();return o.findBelongsTo(this,s,i,u),DS.PromiseObject.create({promise:u.promise})}return null}var d=o.fetchRecord(c)||Ember.RSVP.resolve(c);return DS.PromiseObject.create({promise:d})}).property("data").meta(i)}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.belongsTo=function(n,i){"object"==typeof n&&(i=n,n=void 0),i=i||{};var a={type:n,isRelationship:!0,options:i,kind:"belongsTo"};return i.async?e(n,i,a):Ember.computed(function(e,i){var a,o,s=t(this,"data"),c=t(this,"store");return o="string"==typeof n?c.modelFor(n):n,2===arguments.length?void 0===i?null:i:(a=s[e],r(a)?null:(c.fetchRecord(a),a))}).property("data").meta(a)},DS.Model.reopen({belongsToWillChange:Ember.beforeObserver(function(e,r){if(t(e,"isLoaded")){var n=t(e,r);if(n){var i=t(e,"store"),a=DS.RelationshipChange.createChange(e,n,i,{key:r,kind:"belongsTo",changeType:"remove"});a.sync(),this._changesToSync[r]=a}}}),belongsToDidChange:Ember.immediateObserver(function(e,r){if(t(e,"isLoaded")){var n=t(e,r);if(n){var i=t(e,"store"),a=DS.RelationshipChange.createChange(e,n,i,{key:r,kind:"belongsTo",changeType:"add"});a.sync()}}delete this._changesToSync[r]})})}(),function(){function e(e,r,n){return Ember.computed(function(e){if(this._relationships[e])return this._relationships[e];var i=Ember.RSVP.defer(),a=t(this,e,r,function(t,r){var a=r.links&&r.links[e];return a?t.findHasMany(this,a,n,i):t.findMany(this,r[e],n.type,i)}),o=i.promise.then(function(){return a});return DS.PromiseArray.create({promise:o})}).property("data").meta(n)}function t(e,t,r,a){var o=e._relationships;if(o[t])return o[t];var s=n(e,"data"),c=n(e,"store"),u=o[t]=a.call(e,c,s);return i(u,{owner:e,name:t,isPolymorphic:r.polymorphic})}function r(r,n){n=n||{};var i={type:r,isRelationship:!0,options:n,kind:"hasMany"};return n.async?e(r,n,i):Ember.computed(function(e){return t(this,e,n,function(t,r){return r[e],t.findMany(this,r[e],i.type)})}).property("data").meta(i)}var n=Ember.get,i=(Ember.set,Ember.setProperties);DS.hasMany=function(e,t){return"object"==typeof e&&(t=e,e=void 0),r(e,t)}}(),function(){var e=Ember.get;Ember.set,DS.Model.reopen({didDefineProperty:function(e,t,r){if(r instanceof Ember.Descriptor){var n=r.meta();n.isRelationship&&"belongsTo"===n.kind&&(Ember.addObserver(e,t,null,"belongsToDidChange"),Ember.addBeforeObserver(e,t,null,"belongsToWillChange")),n.parentType=e.constructor}}}),DS.Model.reopenClass({typeForRelationship:function(t){var r=e(this,"relationshipsByName").get(t);return r&&r.type},inverseFor:function(t){function r(t,n,i){i=i||[];var a=e(n,"relationships");if(a){var o=a.get(t);return o&&i.push.apply(i,a.get(t)),t.superclass&&r(t.superclass,n,i),i}}var n=this.typeForRelationship(t);if(!n)return null;var i=this.metaForProperty(t).options;if(null===i.inverse)return null;var a,o;if(i.inverse)a=i.inverse,o=Ember.get(n,"relationshipsByName").get(a).kind;else{var s=r(this,n);if(0===s.length)return null;a=s[0].name,o=s[0].kind}return{type:n,name:a,kind:o}},relationships:Ember.computed(function(){var e=new Ember.MapWithDefault({defaultValue:function(){return[]}});return this.eachComputedProperty(function(t,r){if(r.isRelationship){"string"==typeof r.type&&(r.type=this.store.modelFor(r.type));var n=e.get(r.type);n.push({name:t,kind:r.kind})}}),e}),relationshipNames:Ember.computed(function(){var e={hasMany:[],belongsTo:[]};return this.eachComputedProperty(function(t,r){r.isRelationship&&e[r.kind].push(t)}),e}),relatedTypes:Ember.computed(function(){var t,r=Ember.A();return this.eachComputedProperty(function(n,i){i.isRelationship&&(t=i.type,"string"==typeof t&&(t=e(this,t,!1)||this.store.modelFor(t)),r.contains(t)||r.push(t))}),r}),relationshipsByName:Ember.computed(function(){var e,t=Ember.Map.create();return this.eachComputedProperty(function(r,n){n.isRelationship&&(n.key=r,e=n.type,e||"hasMany"!==n.kind?e||(e=r):e=Ember.String.singularize(r),"string"==typeof e&&(n.type=this.store.modelFor(e)),t.set(r,n))}),t}),fields:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isRelationship?e.set(t,r.kind):r.isAttribute&&e.set(t,"attribute")}),e}),eachRelationship:function(t,r){e(this,"relationshipsByName").forEach(function(e,n){t.call(r,e,n)})},eachRelatedType:function(t,r){e(this,"relatedTypes").forEach(function(e){t.call(r,e)})}}),DS.Model.reopen({eachRelationship:function(e,t){this.constructor.eachRelationship(e,t)}})}(),function(){var e=Ember.get;Ember.set;var t=Ember.run.once,r=Ember.EnumerableUtils.forEach;DS.RecordArrayManager=Ember.Object.extend({init:function(){this.filteredRecordArrays=Ember.MapWithDefault.create({defaultValue:function(){return[]}}),this.changedRecords=[]},recordDidChange:function(e){this.changedRecords.push(e),t(this,this.updateRecordArrays)},recordArraysForRecord:function(e){return e._recordArrays=e._recordArrays||Ember.OrderedSet.create(),e._recordArrays},updateRecordArrays:function(){r(this.changedRecords,function(t){var n,i=t.constructor,a=this.filteredRecordArrays.get(i);r(a,function(r){n=e(r,"filterFunction"),this.updateRecordArray(r,n,i,t)},this);var o=t._loadingRecordArrays;if(o){for(var s=0,c=o.length;c>s;s++)o[s].loadedRecord();t._loadingRecordArrays=[]}},this),this.changedRecords=[]},updateRecordArray:function(e,t,r,n){var i;i=t?t(n):!0;var a=this.recordArraysForRecord(n);i?(a.add(e),e.addRecord(n)):i||(a.remove(e),e.removeRecord(n))},remove:function(e){var t=e._recordArrays;t&&r(t,function(t){t.removeRecord(e)})},updateFilter:function(t,r,n){for(var i,a=this.store.typeMapFor(r),o=a.records,s=0,c=o.length;c>s;s++)i=o[s],e(i,"isDeleted")||e(i,"isEmpty")||this.updateRecordArray(t,n,r,i)},createManyArray:function(e,t){var n=DS.ManyArray.create({type:e,content:t,store:this.store});return r(t,function(e){var t=this.recordArraysForRecord(e);t.add(n)},this),n},registerFilteredRecordArray:function(e,t,r){var n=this.filteredRecordArrays.get(t);n.push(e),this.updateFilter(e,t,r)},registerWaitingRecordArray:function(e,t){var r=e._loadingRecordArrays||[];r.push(t),e._loadingRecordArrays=r}})}(),function(){var e=Ember.get;Ember.set;var t=Ember.ArrayPolyfills.map,r=["description","fileName","lineNumber","message","name","number","stack"];DS.InvalidError=function(e){var t=Error.prototype.constructor.call(this,"The backend rejected the commit because it was invalid: "+Ember.inspect(e));this.errors=e;for(var n=0,i=r.length;i>n;n++)this[r[n]]=t[r[n]]},DS.InvalidError.prototype=Ember.create(Error.prototype),DS.Adapter=Ember.Object.extend(DS._Mappable,{find:Ember.required(Function),findAll:null,findQuery:null,generateIdForRecord:null,serialize:function(t,r){return e(t,"store").serializerFor(t.constructor.typeKey).serialize(t,r)},createRecord:Ember.required(Function),updateRecord:Ember.required(Function),deleteRecord:Ember.required(Function),findMany:function(e,r,n){var i=t.call(n,function(t){return this.find(e,r,t)},this);return Ember.RSVP.all(i)}})}(),function(){var e=Ember.get,t=Ember.String.fmt,r=Ember.EnumerableUtils.indexOf,n=0;DS.FixtureAdapter=DS.Adapter.extend({serializer:null,simulateRemoteResponse:!0,latency:50,fixturesForType:function(e){if(e.FIXTURES){var r=Ember.A(e.FIXTURES);return r.map(function(e){var r=typeof e.id;if("number"!==r&&"string"!==r)throw new Error(t("the id property must be defined as a number or string for fixture %@",[e]));return e.id=e.id+"",e})}return null},queryFixtures:function(){},updateFixtures:function(e,t){e.FIXTURES||(e.FIXTURES=[]);var r=e.FIXTURES;this.deleteLoadedFixture(e,t),r.push(t)},mockJSON:function(e,t,r){return e.serializerFor(t).serialize(r,{includeId:!0})},generateIdForRecord:function(){return"fixture-"+n++},find:function(e,t,r){var n,i=this.fixturesForType(t);return i&&(n=Ember.A(i).findProperty("id",r)),n?this.simulateRemoteCall(function(){return n},this):void 0},findMany:function(e,t,n){var i=this.fixturesForType(t);return i&&(i=i.filter(function(e){return-1!==r(n,e.id)})),i?this.simulateRemoteCall(function(){return i},this):void 0},findAll:function(e,t){var r=this.fixturesForType(t);return this.simulateRemoteCall(function(){return r},this)},findQuery:function(e,t,r){var n=this.fixturesForType(t);return n=this.queryFixtures(n,r,t),n?this.simulateRemoteCall(function(){return n},this):void 0},createRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.updateFixtures(t,n),this.simulateRemoteCall(function(){return n},this)},updateRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.updateFixtures(t,n),this.simulateRemoteCall(function(){return n},this)},deleteRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.deleteLoadedFixture(t,n),this.simulateRemoteCall(function(){return null})},deleteLoadedFixture:function(e,t){var n=this.findExistingFixture(e,t);if(n){var i=r(e.FIXTURES,n);return e.FIXTURES.splice(i,1),!0}},findExistingFixture:function(t,r){var n=this.fixturesForType(t),i=e(r,"id");return this.findFixtureById(n,i)},findFixtureById:function(t,r){return Ember.A(t).find(function(t){return""+e(t,"id")==""+r?!0:!1})},simulateRemoteCall:function(t,r){var n=this;return new Ember.RSVP.Promise(function(i){e(n,"simulateRemoteResponse")?Ember.run.later(function(){i(t.call(r))},e(n,"latency")):Ember.run.once(function(){i(t.call(r))})})}})}(),function(){function e(e){return null==e?null:e+""}var t=Ember.get;Ember.set;var r=Ember.ArrayPolyfills.forEach,n=Ember.ArrayPolyfills.map;DS.RESTSerializer=DS.JSONSerializer.extend({normalize:function(e,t,r){return this.normalizeId(t),this.normalizeUsingDeclaredMapping(e,t),this.normalizeAttributes(e,t),this.normalizeRelationships(e,t),this.normalizeHash&&this.normalizeHash[r]?this.normalizeHash[r](t):this._super(e,t,r)},normalizePayload:function(e,t){return t},normalizeId:function(e){var r=t(this,"primaryKey");"id"!==r&&(e.id=e[r],delete e[r])},normalizeUsingDeclaredMapping:function(e,r){var n,i,a=t(this,"attrs");if(a)for(i in a)n=a[i],r[i]=r[n],delete r[n]},normalizeAttributes:function(e,t){var r;this.keyForAttribute&&e.eachAttribute(function(e){r=this.keyForAttribute(e),e!==r&&(t[e]=t[r],delete t[r])},this)},normalizeRelationships:function(e,t){var r;this.keyForRelationship&&e.eachRelationship(function(e,n){r=this.keyForRelationship(e,n.kind),e!==r&&(t[e]=t[r],delete t[r])},this)},extractSingle:function(t,n,i,a){i=this.normalizePayload(n,i);var o,s=n.typeKey;for(var c in i){var u=this.typeForRoot(c),d=u===s;d&&"array"!==Ember.typeOf(i[c])?o=this.normalize(n,i[c],c):(t.modelFor(u),r.call(i[c],function(r){var n=this.typeForRoot(c),i=t.modelFor(n),s=t.serializerFor(i);r=s.normalize(i,r,c);var u=d&&!a&&!o,l=d&&e(r.id)===a;u||l?o=r:t.push(n,r)},this))}return o},extractArray:function(e,t,r){r=this.normalizePayload(t,r);var i,a=t.typeKey;for(var o in r){var s=o,c=!1;"_"===o.charAt(0)&&(c=!0,s=o.substr(1));var u=this.typeForRoot(s),d=e.modelFor(u),l=e.serializerFor(d),h=!c&&u===a,f=n.call(r[o],function(e){return l.normalize(d,e,o)},this);h?i=f:e.pushMany(u,f)}return i},pushPayload:function(e,t){t=this.normalizePayload(null,t);for(var r in t){var i=this.typeForRoot(r),a=e.modelFor(i),o=n.call(t[r],function(e){return this.normalize(a,e,r)},this);e.pushMany(i,o)}},typeForRoot:function(e){return Ember.String.singularize(e)},serialize:function(){return this._super.apply(this,arguments)},serializeIntoHash:function(e,t,r,n){e[t.typeKey]=this.serialize(r,n)},serializePolymorphicType:function(e,r,n){var i=n.key,a=t(e,i);i=this.keyForAttribute?this.keyForAttribute(i):i,r[i+"Type"]=a.constructor.typeKey}})}(),function(){var e=Ember.get;Ember.set;var t=Ember.ArrayPolyfills.forEach;DS.RESTAdapter=DS.Adapter.extend({defaultSerializer:"_rest",find:function(e,t,r){return this.ajax(this.buildURL(t.typeKey,r),"GET")},findAll:function(e,t,r){var n;return r&&(n={since:r}),this.ajax(this.buildURL(t.typeKey),"GET",{data:n})},findQuery:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:r})},findMany:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:{ids:r}})},findHasMany:function(t,r,n){var i=e(this,"host"),a=e(r,"id"),o=r.constructor.typeKey;return i&&"/"===n.charAt(0)&&"/"!==n.charAt(1)&&(n=i+n),this.ajax(this.urlPrefix(n,this.buildURL(o,a)),"GET")},findBelongsTo:function(t,r,n){var i=e(r,"id"),a=r.constructor.typeKey;return this.ajax(this.urlPrefix(n,this.buildURL(a,i)),"GET")},createRecord:function(e,t,r){var n={},i=e.serializerFor(t.typeKey);return i.serializeIntoHash(n,t,r,{includeId:!0}),this.ajax(this.buildURL(t.typeKey),"POST",{data:n})},updateRecord:function(t,r,n){var i={},a=t.serializerFor(r.typeKey);a.serializeIntoHash(i,r,n);var o=e(n,"id");return this.ajax(this.buildURL(r.typeKey,o),"PUT",{data:i})},deleteRecord:function(t,r,n){var i=e(n,"id");return this.ajax(this.buildURL(r.typeKey,i),"DELETE")},buildURL:function(t,r){var n=[],i=e(this,"host"),a=this.urlPrefix();return t&&n.push(this.pathForType(t)),r&&n.push(r),a&&n.unshift(a),n=n.join("/"),!i&&n&&(n="/"+n),n},urlPrefix:function(t,r){var n=e(this,"host"),i=e(this,"namespace"),a=[];return t?"/"===t.charAt(0)?n&&(t=t.slice(1),a.push(n)):/^http(s)?:\/\//.test(t)||a.push(r):(n&&a.push(n),i&&a.push(i)),t&&a.push(t),a.join("/")},pathForType:function(e){return Ember.String.pluralize(e)},ajaxError:function(e){return e&&(e.then=null),e},ajax:function(e,t,r){var n=this;return new Ember.RSVP.Promise(function(i,a){r=n.ajaxOptions(e,t,r),r.success=function(e){Ember.run(null,i,e)},r.error=function(e){Ember.run(null,a,n.ajaxError(e))},Ember.$.ajax(r)})},ajaxOptions:function(e,r,n){if(n=n||{},n.url=e,n.type=r,n.dataType="json",n.context=this,n.data&&"GET"!==r&&(n.contentType="application/json; charset=utf-8",n.data=JSON.stringify(n.data)),void 0!==this.headers){var i=this.headers;n.beforeSend=function(e){t.call(Ember.keys(i),function(t){e.setRequestHeader(t,i[t])})}}return n}})}(),function(){DS.Model.reopen({_debugInfo:function(){var e=["id"],t={belongsTo:[],hasMany:[]},r=[];this.eachAttribute(function(t){e.push(t)},this),this.eachRelationship(function(e,n){t[n.kind].push(e),r.push(e)});var n=[{name:"Attributes",properties:e,expand:!0},{name:"Belongs To",properties:t.belongsTo,expand:!0},{name:"Has Many",properties:t.hasMany,expand:!0},{name:"Flags",properties:["isLoaded","isDirty","isSaving","isDeleted","isError","isNew","isValid"]}];return{propertyInfo:{includeOtherProperties:!0,groups:n,expensiveProperties:r}}}})}(),function(){Ember.String.pluralize=function(e){return Ember.Inflector.inflector.pluralize(e)},Ember.String.singularize=function(e){return Ember.Inflector.inflector.singularize(e)}}(),function(){function e(e,t){for(var r=0,n=t.length;n>r;r++)e.uncountable[t[r]]=!0}function t(e,t){for(var r,n=0,i=t.length;i>n;n++)r=t[n],e.irregular[r[0]]=r[1],e.irregularInverse[r[1]]=r[0]}function r(r){r=r||{},r.uncountable=r.uncountable||{},r.irregularPairs=r.irregularPairs||{};var n=this.rules={plurals:r.plurals||[],singular:r.singular||[],irregular:{},irregularInverse:{},uncountable:{}};e(n,r.uncountable),t(n,r.irregularPairs)}var n=/^\s*$/;r.prototype={plural:function(e,t){this.rules.plurals.push([e,t])},singular:function(e,t){this.rules.singular.push([e,t])},uncountable:function(t){e(this.rules,[t])},irregular:function(e,r){t(this.rules,[[e,r]])},pluralize:function(e){return this.inflect(e,this.rules.plurals,this.rules.irregular)},singularize:function(e){return this.inflect(e,this.rules.singular,this.rules.irregularInverse)},inflect:function(e,t,r){var i,a,o,s,c,u,d,l;if(c=n.test(e))return e;if(s=e.toLowerCase(),u=this.rules.uncountable[s])return e;if(d=r&&r[s])return d;for(var h=t.length,f=0;h>f&&(i=t[h-1],l=i[0],!l.test(e));h--);return i=i||[],l=i[0],a=i[1],o=e.replace(l,a)}},Ember.Inflector=r}(),function(){Ember.Inflector.defaultRules={plurals:[[/$/,"s"],[/s$/i,"s"],[/^(ax|test)is$/i,"$1es"],[/(octop|vir)us$/i,"$1i"],[/(octop|vir)i$/i,"$1i"],[/(alias|status)$/i,"$1es"],[/(bu)s$/i,"$1ses"],[/(buffal|tomat)o$/i,"$1oes"],[/([ti])um$/i,"$1a"],[/([ti])a$/i,"$1a"],[/sis$/i,"ses"],[/(?:([^f])fe|([lr])f)$/i,"$1$2ves"],[/(hive)$/i,"$1s"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/(x|ch|ss|sh)$/i,"$1es"],[/(matr|vert|ind)(?:ix|ex)$/i,"$1ices"],[/^(m|l)ouse$/i,"$1ice"],[/^(m|l)ice$/i,"$1ice"],[/^(ox)$/i,"$1en"],[/^(oxen)$/i,"$1"],[/(quiz)$/i,"$1zes"]],singular:[[/s$/i,""],[/(ss)$/i,"$1"],[/(n)ews$/i,"$1ews"],[/([ti])a$/i,"$1um"],[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i,"$1sis"],[/(^analy)(sis|ses)$/i,"$1sis"],[/([^f])ves$/i,"$1fe"],[/(hive)s$/i,"$1"],[/(tive)s$/i,"$1"],[/([lr])ves$/i,"$1f"],[/([^aeiouy]|qu)ies$/i,"$1y"],[/(s)eries$/i,"$1eries"],[/(m)ovies$/i,"$1ovie"],[/(x|ch|ss|sh)es$/i,"$1"],[/^(m|l)ice$/i,"$1ouse"],[/(bus)(es)?$/i,"$1"],[/(o)es$/i,"$1"],[/(shoe)s$/i,"$1"],[/(cris|test)(is|es)$/i,"$1is"],[/^(a)x[ie]s$/i,"$1xis"],[/(octop|vir)(us|i)$/i,"$1us"],[/(alias|status)(es)?$/i,"$1"],[/^(ox)en/i,"$1"],[/(vert|ind)ices$/i,"$1ex"],[/(matr)ices$/i,"$1ix"],[/(quiz)zes$/i,"$1"],[/(database)s$/i,"$1"]],irregularPairs:[["person","people"],["man","men"],["child","children"],["sex","sexes"],["move","moves"],["cow","kine"],["zombie","zombies"]],uncountable:["equipment","information","rice","money","species","series","fish","sheep","jeans","police"]}}(),function(){(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.String)&&(String.prototype.pluralize=function(){return Ember.String.pluralize(this)},String.prototype.singularize=function(){return Ember.String.singularize(this)})}(),function(){Ember.Inflector.inflector=new Ember.Inflector(Ember.Inflector.defaultRules)}(),function(){function e(n,i,a,o,s){var c=t(i,"attrs");c&&a.eachRelationship(function(i,a){var u,d,l,h,f=c[i],p=n.serializerFor(a.type.typeKey),m=t(p,"primaryKey");if("hasMany"===a.kind&&f&&("always"===f.embedded||"load"===f.embedded)){if(d="_"+Ember.String.pluralize(a.type.typeKey),u=this.keyForRelationship(i,a.kind),l=this.keyForAttribute(i),h=[],!o[l])return;s[d]=s[d]||[],r(o[l],function(t){var r=n.modelFor(a.type.typeKey);e(n,p,r,t,s),h.push(t[m]),s[d].push(t)}),o[u]=h,delete o[l]}},i)}var t=Ember.get,r=Ember.EnumerableUtils.forEach;DS.ActiveModelSerializer=DS.RESTSerializer.extend({keyForAttribute:function(e){return Ember.String.decamelize(e)},keyForRelationship:function(e,t){return e=Ember.String.decamelize(e),"belongsTo"===t?e+"_id":"hasMany"===t?Ember.String.singularize(e)+"_ids":e},serializeHasMany:function(e,r,n){var i=n.key,a=t(this,"attrs"),o=a&&a[i]&&"always"===a[i].embedded;o&&(r[this.keyForAttribute(i)]=t(e,i).map(function(e){var r=e.serialize(),n=t(this,"primaryKey");return r[n]=t(e,n),r},this))},serializeIntoHash:function(e,t,r,n){var i=Ember.String.decamelize(t.typeKey);e[i]=this.serialize(r,n)},serializePolymorphicType:function(e,r,n){var i=n.key,a=t(e,i);i=this.keyForAttribute(i),r[i+"_type"]=Ember.String.capitalize(a.constructor.typeKey)},typeForRoot:function(e){var t=Ember.String.camelize(e);return Ember.String.singularize(t)},normalizeRelationships:function(e,t){var n,i;this.keyForRelationship&&e.eachRelationship(function(e,a){if(a.options.polymorphic){if(n=this.keyForAttribute(e),i=t[n],i&&i.type)i.type=this.typeForRoot(i.type);else if(i&&"hasMany"===a.kind){var o=this;r(i,function(e){e.type=o.typeForRoot(e.type)})}}else n=this.keyForRelationship(e,a.kind),i=t[n];t[e]=i,e!==n&&delete t[n]},this)},extractSingle:function(t,r,n,i,a){var o=this.keyForAttribute(r.typeKey),s=n[o];return e(t,this,r,s,n),this._super(t,r,n,i,a)},extractArray:function(t,n,i){var a=this.keyForAttribute(n.typeKey),o=i[Ember.String.pluralize(a)];return r(o,function(r){e(t,this,n,r,i)},this),this._super(t,n,i)}})}(),function(){var e=Ember.EnumerableUtils.forEach;DS.ActiveModelAdapter=DS.RESTAdapter.extend({defaultSerializer:"_ams",pathForType:function(e){var t=Ember.String.decamelize(e);return Ember.String.pluralize(t)},ajaxError:function(t){var r=this._super(t);if(t&&422===t.status){var n=Ember.$.parseJSON(t.responseText).errors,i={};return e(Ember.keys(n),function(e){i[Ember.String.camelize(e)]=n[e]}),new DS.InvalidError(i)}return r}})}(),function(){Ember.onLoad("Ember.Application",function(e){e.initializer({name:"activeModelAdapter",initialize:function(e,t){t.register("serializer:_ams",DS.ActiveModelSerializer),t.register("adapter:_ams",DS.ActiveModelAdapter)}})})}()}(),"undefined"==typeof location||"localhost"!==location.hostname&&"127.0.0.1"!==location.hostname||Ember.Logger.warn("You are running a production build of Ember on localhost and won't receive detailed error messages. If you want full error messages please use the non-minified build provided on the Ember website.");
|
data/dist/ember-data.prod.js
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: Ember Data
|
3
|
+
// Copyright: Copyright 2011-2013 Tilde Inc. and contributors.
|
4
|
+
// Portions Copyright 2011 LivingSocial Inc.
|
5
|
+
// License: Licensed under MIT license (see license.js)
|
6
|
+
// ==========================================================================
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
// Version: v1.0.0-beta.3-48-gb47afef
|
11
|
+
// Last commit: b47afef (2013-10-08 19:07:59 -0700)
|
12
|
+
|
13
|
+
|
1
14
|
(function() {
|
2
15
|
var define, requireModule;
|
3
16
|
|
@@ -51,12 +64,16 @@ var define, requireModule;
|
|
51
64
|
|
52
65
|
if ('undefined' === typeof DS) {
|
53
66
|
DS = Ember.Namespace.create({
|
54
|
-
VERSION: '1.0.0-beta.
|
67
|
+
VERSION: '1.0.0-beta.2'
|
55
68
|
});
|
56
69
|
|
57
70
|
if ('undefined' !== typeof window) {
|
58
71
|
window.DS = DS;
|
59
72
|
}
|
73
|
+
|
74
|
+
if (Ember.libraries) {
|
75
|
+
Ember.libraries.registerCoreLibrary('Ember Data', DS.VERSION);
|
76
|
+
}
|
60
77
|
}
|
61
78
|
})();
|
62
79
|
|
@@ -95,8 +112,6 @@ DS.JSONSerializer = Ember.Object.extend({
|
|
95
112
|
// SERIALIZE
|
96
113
|
|
97
114
|
serialize: function(record, options) {
|
98
|
-
var store = get(this, 'store');
|
99
|
-
|
100
115
|
var json = {};
|
101
116
|
|
102
117
|
if (options && options.includeId) {
|
@@ -133,7 +148,7 @@ DS.JSONSerializer = Ember.Object.extend({
|
|
133
148
|
|
134
149
|
// if provided, use the mapping provided by `attrs` in
|
135
150
|
// the serializer
|
136
|
-
key = attrs && attrs[key] || key;
|
151
|
+
key = attrs && attrs[key] || (this.keyForAttribute ? this.keyForAttribute(key) : key);
|
137
152
|
|
138
153
|
json[key] = value;
|
139
154
|
},
|
@@ -143,12 +158,16 @@ DS.JSONSerializer = Ember.Object.extend({
|
|
143
158
|
|
144
159
|
var belongsTo = get(record, key);
|
145
160
|
|
146
|
-
|
161
|
+
key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;
|
147
162
|
|
148
|
-
|
163
|
+
if (isNone(belongsTo)) {
|
164
|
+
json[key] = belongsTo;
|
165
|
+
} else {
|
166
|
+
json[key] = get(belongsTo, 'id');
|
167
|
+
}
|
149
168
|
|
150
169
|
if (relationship.options.polymorphic) {
|
151
|
-
json
|
170
|
+
this.serializePolymorphicType(record, json, relationship);
|
152
171
|
}
|
153
172
|
},
|
154
173
|
|
@@ -163,6 +182,11 @@ DS.JSONSerializer = Ember.Object.extend({
|
|
163
182
|
}
|
164
183
|
},
|
165
184
|
|
185
|
+
/**
|
186
|
+
You can use this method to customize how polymorphic objects are serialized.
|
187
|
+
*/
|
188
|
+
serializePolymorphicType: Ember.K,
|
189
|
+
|
166
190
|
// EXTRACT
|
167
191
|
|
168
192
|
extract: function(store, type, payload, id, requestType) {
|
@@ -182,6 +206,7 @@ DS.JSONSerializer = Ember.Object.extend({
|
|
182
206
|
extractDeleteRecord: aliasMethod('extractSave'),
|
183
207
|
|
184
208
|
extractFind: aliasMethod('extractSingle'),
|
209
|
+
extractFindBelongsTo: aliasMethod('extractSingle'),
|
185
210
|
extractSave: aliasMethod('extractSingle'),
|
186
211
|
|
187
212
|
extractSingle: function(store, type, payload) {
|
@@ -201,16 +226,10 @@ DS.JSONSerializer = Ember.Object.extend({
|
|
201
226
|
|
202
227
|
// HELPERS
|
203
228
|
|
204
|
-
|
205
|
-
|
206
|
-
return data[key + "_type"];
|
207
|
-
} else {
|
208
|
-
return relationship.type;
|
209
|
-
}
|
210
|
-
},
|
229
|
+
transformFor: function(attributeType, skipAssertion) {
|
230
|
+
var transform = this.container.lookup('transform:' + attributeType);
|
211
231
|
|
212
|
-
|
213
|
-
return this.container.lookup('transform:' + attributeType);
|
232
|
+
return transform;
|
214
233
|
}
|
215
234
|
});
|
216
235
|
|
@@ -226,6 +245,11 @@ var get = Ember.get, capitalize = Ember.String.capitalize, underscore = Ember.St
|
|
226
245
|
|
227
246
|
/**
|
228
247
|
Extend `Ember.DataAdapter` with ED specific code.
|
248
|
+
|
249
|
+
@class DebugAdapter
|
250
|
+
@namespace DS
|
251
|
+
@extends Ember.DataAdapter
|
252
|
+
@private
|
229
253
|
*/
|
230
254
|
DS.DebugAdapter = Ember.DataAdapter.extend({
|
231
255
|
getFilters: function() {
|
@@ -242,7 +266,7 @@ DS.DebugAdapter = Ember.DataAdapter.extend({
|
|
242
266
|
|
243
267
|
columnsForType: function(type) {
|
244
268
|
var columns = [{ name: 'id', desc: 'Id' }], count = 0, self = this;
|
245
|
-
|
269
|
+
get(type, 'attributes').forEach(function(name, meta) {
|
246
270
|
if (count++ > self.attributeLimit) { return false; }
|
247
271
|
var desc = capitalize(underscore(name).replace('_', ' '));
|
248
272
|
columns.push({ name: name, desc: desc });
|
@@ -438,7 +462,7 @@ DS.NumberTransform = DS.Transform.extend({
|
|
438
462
|
|
439
463
|
|
440
464
|
(function() {
|
441
|
-
var none = Ember.isNone
|
465
|
+
var none = Ember.isNone;
|
442
466
|
|
443
467
|
DS.StringTransform = DS.Transform.extend({
|
444
468
|
|
@@ -451,6 +475,7 @@ DS.StringTransform = DS.Transform.extend({
|
|
451
475
|
}
|
452
476
|
|
453
477
|
});
|
478
|
+
|
454
479
|
})();
|
455
480
|
|
456
481
|
|
@@ -684,6 +709,14 @@ DS.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
|
|
684
709
|
|
685
710
|
removeRecord: function(record) {
|
686
711
|
get(this, 'content').removeObject(record);
|
712
|
+
},
|
713
|
+
|
714
|
+
save: function() {
|
715
|
+
var promise = Ember.RSVP.all(this.invoke("save")).then(function(array) {
|
716
|
+
return Ember.A(array);
|
717
|
+
});
|
718
|
+
|
719
|
+
return DS.PromiseArray.create({ promise: promise });
|
687
720
|
}
|
688
721
|
});
|
689
722
|
|
@@ -745,11 +778,13 @@ DS.AdapterPopulatedRecordArray = DS.RecordArray.extend({
|
|
745
778
|
load: function(data) {
|
746
779
|
var store = get(this, 'store'),
|
747
780
|
type = get(this, 'type'),
|
748
|
-
records = store.pushMany(type, data)
|
781
|
+
records = store.pushMany(type, data),
|
782
|
+
meta = store.metadataFor(type);
|
749
783
|
|
750
784
|
this.setProperties({
|
751
785
|
content: Ember.A(records),
|
752
|
-
isLoaded: true
|
786
|
+
isLoaded: true,
|
787
|
+
meta: meta
|
753
788
|
});
|
754
789
|
|
755
790
|
// TODO: does triggering didLoad event should be the last action of the runLoop?
|
@@ -783,11 +818,11 @@ var map = Ember.EnumerableUtils.map;
|
|
783
818
|
defined:
|
784
819
|
|
785
820
|
App.Post = DS.Model.extend({
|
786
|
-
comments: DS.hasMany('
|
821
|
+
comments: DS.hasMany('comment')
|
787
822
|
});
|
788
823
|
|
789
824
|
App.Comment = DS.Model.extend({
|
790
|
-
post: DS.belongsTo('
|
825
|
+
post: DS.belongsTo('post')
|
791
826
|
});
|
792
827
|
|
793
828
|
If you created a new instance of `App.Post` and added
|
@@ -844,10 +879,11 @@ DS.ManyArray = DS.RecordArray.extend({
|
|
844
879
|
fetch: function() {
|
845
880
|
var records = get(this, 'content'),
|
846
881
|
store = get(this, 'store'),
|
847
|
-
owner = get(this, 'owner')
|
882
|
+
owner = get(this, 'owner'),
|
883
|
+
resolver = Ember.RSVP.defer();
|
848
884
|
|
849
885
|
var unloadedRecords = records.filterProperty('isEmpty', true);
|
850
|
-
store.fetchMany(unloadedRecords, owner);
|
886
|
+
store.fetchMany(unloadedRecords, owner, resolver);
|
851
887
|
},
|
852
888
|
|
853
889
|
// Overrides Ember.Array's replace method to implement
|
@@ -862,7 +898,7 @@ DS.ManyArray = DS.RecordArray.extend({
|
|
862
898
|
},
|
863
899
|
|
864
900
|
arrangedContentDidChange: function() {
|
865
|
-
this
|
901
|
+
Ember.run.once(this, 'fetch');
|
866
902
|
},
|
867
903
|
|
868
904
|
arrayContentWillChange: function(index, removed, added) {
|
@@ -1131,7 +1167,6 @@ var isNone = Ember.isNone;
|
|
1131
1167
|
var forEach = Ember.EnumerableUtils.forEach;
|
1132
1168
|
var indexOf = Ember.EnumerableUtils.indexOf;
|
1133
1169
|
var map = Ember.EnumerableUtils.map;
|
1134
|
-
var OrderedSet = Ember.OrderedSet;
|
1135
1170
|
var resolve = Ember.RSVP.resolve;
|
1136
1171
|
|
1137
1172
|
// Implementors Note:
|
@@ -1341,7 +1376,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1341
1376
|
@returns String if the adapter can generate one, an ID
|
1342
1377
|
*/
|
1343
1378
|
_generateId: function(type) {
|
1344
|
-
var adapter = this.
|
1379
|
+
var adapter = this.adapterFor(type);
|
1345
1380
|
|
1346
1381
|
if (adapter && adapter.generateIdForRecord) {
|
1347
1382
|
return adapter.generateIdForRecord(this);
|
@@ -1445,12 +1480,10 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1445
1480
|
findById: function(type, id) {
|
1446
1481
|
type = this.modelFor(type);
|
1447
1482
|
|
1448
|
-
var record = this.
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
return promiseObject(resolve(record));
|
1453
|
-
}
|
1483
|
+
var record = this.recordForId(type, id);
|
1484
|
+
|
1485
|
+
var promise = this.fetchRecord(record) || resolve(record);
|
1486
|
+
return promiseObject(promise);
|
1454
1487
|
},
|
1455
1488
|
|
1456
1489
|
/**
|
@@ -1483,13 +1516,17 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1483
1516
|
@returns Promise
|
1484
1517
|
*/
|
1485
1518
|
fetchRecord: function(record) {
|
1519
|
+
if (isNone(record)) { return null; }
|
1520
|
+
if (record._loadingPromise) { return record._loadingPromise; }
|
1521
|
+
if (!get(record, 'isEmpty')) { return null; }
|
1522
|
+
|
1486
1523
|
var type = record.constructor,
|
1487
1524
|
id = get(record, 'id'),
|
1488
1525
|
resolver = Ember.RSVP.defer();
|
1489
1526
|
|
1490
|
-
record.loadingData();
|
1527
|
+
record.loadingData(resolver.promise);
|
1491
1528
|
|
1492
|
-
var adapter = this.
|
1529
|
+
var adapter = this.adapterFor(type);
|
1493
1530
|
|
1494
1531
|
|
1495
1532
|
|
@@ -1502,7 +1539,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1502
1539
|
Get a record by a given type and ID without triggering a fetch.
|
1503
1540
|
|
1504
1541
|
This method will synchronously return the record if it's available.
|
1505
|
-
Otherwise, it will return
|
1542
|
+
Otherwise, it will return null.
|
1506
1543
|
|
1507
1544
|
```js
|
1508
1545
|
var post = store.getById('post', 1);
|
@@ -1518,7 +1555,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1518
1555
|
if (this.hasRecordForId(type, id)) {
|
1519
1556
|
return this.recordForId(type, id);
|
1520
1557
|
} else {
|
1521
|
-
return
|
1558
|
+
return null;
|
1522
1559
|
}
|
1523
1560
|
},
|
1524
1561
|
|
@@ -1537,8 +1574,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1537
1574
|
*/
|
1538
1575
|
reloadRecord: function(record, resolver) {
|
1539
1576
|
var type = record.constructor,
|
1540
|
-
adapter = this.
|
1541
|
-
store = this,
|
1577
|
+
adapter = this.adapterFor(type),
|
1542
1578
|
id = get(record, 'id');
|
1543
1579
|
|
1544
1580
|
|
@@ -1578,7 +1614,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1578
1614
|
|
1579
1615
|
forEach(recordsByTypeMap, function(type, records) {
|
1580
1616
|
var ids = records.mapProperty('id'),
|
1581
|
-
adapter = this.
|
1617
|
+
adapter = this.adapterFor(type);
|
1582
1618
|
|
1583
1619
|
|
1584
1620
|
|
@@ -1589,7 +1625,8 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1589
1625
|
/**
|
1590
1626
|
Returns true if a record for a given type and ID is already loaded.
|
1591
1627
|
|
1592
|
-
@
|
1628
|
+
@method hasRecordForId
|
1629
|
+
@param {DS.Model} type
|
1593
1630
|
@param {String|Integer} id
|
1594
1631
|
@returns Boolean
|
1595
1632
|
*/
|
@@ -1603,6 +1640,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1603
1640
|
Returns id record for a given type and ID. If one isn't already loaded,
|
1604
1641
|
it builds a new record and leaves it in the `empty` state.
|
1605
1642
|
|
1643
|
+
@method recordForId
|
1606
1644
|
@param {String} type
|
1607
1645
|
@param {String|Integer} id
|
1608
1646
|
@returns DS.Model
|
@@ -1670,6 +1708,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1670
1708
|
The usual use-case is for the server to register a URL as a link, and
|
1671
1709
|
then use that URL in the future to make a request for the relationship.
|
1672
1710
|
|
1711
|
+
@method findHasMany
|
1673
1712
|
@private
|
1674
1713
|
@param {DS.Model} owner
|
1675
1714
|
@param {any} link
|
@@ -1678,7 +1717,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1678
1717
|
@return DS.ManyArray
|
1679
1718
|
*/
|
1680
1719
|
findHasMany: function(owner, link, relationship, resolver) {
|
1681
|
-
var adapter = this.
|
1720
|
+
var adapter = this.adapterFor(owner.constructor);
|
1682
1721
|
|
1683
1722
|
|
1684
1723
|
|
@@ -1687,6 +1726,14 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1687
1726
|
return records;
|
1688
1727
|
},
|
1689
1728
|
|
1729
|
+
findBelongsTo: function(owner, link, relationship, resolver) {
|
1730
|
+
var adapter = this.adapterFor(owner.constructor);
|
1731
|
+
|
1732
|
+
|
1733
|
+
|
1734
|
+
_findBelongsTo(adapter, this, owner, link, relationship, resolver);
|
1735
|
+
},
|
1736
|
+
|
1690
1737
|
/**
|
1691
1738
|
This method delegates a query to the adapter. This is the one place where
|
1692
1739
|
adapter-level semantics are exposed to the application.
|
@@ -1714,7 +1761,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1714
1761
|
store: this
|
1715
1762
|
});
|
1716
1763
|
|
1717
|
-
var adapter = this.
|
1764
|
+
var adapter = this.adapterFor(type),
|
1718
1765
|
resolver = Ember.RSVP.defer();
|
1719
1766
|
|
1720
1767
|
|
@@ -1748,7 +1795,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1748
1795
|
@returns Promise
|
1749
1796
|
*/
|
1750
1797
|
fetchAll: function(type, array) {
|
1751
|
-
var adapter = this.
|
1798
|
+
var adapter = this.adapterFor(type),
|
1752
1799
|
sinceToken = this.typeMapFor(type).metadata.since,
|
1753
1800
|
resolver = Ember.RSVP.defer();
|
1754
1801
|
|
@@ -1805,6 +1852,24 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1805
1852
|
return array;
|
1806
1853
|
},
|
1807
1854
|
|
1855
|
+
|
1856
|
+
/**
|
1857
|
+
This method unloads all of the known records for a given type.
|
1858
|
+
|
1859
|
+
@method unloadAll
|
1860
|
+
@param {Class} type
|
1861
|
+
*/
|
1862
|
+
unloadAll: function(type) {
|
1863
|
+
type = this.modelFor(type);
|
1864
|
+
|
1865
|
+
var typeMap = this.typeMapFor(type),
|
1866
|
+
records = typeMap.records, record;
|
1867
|
+
|
1868
|
+
while(record = records.pop()) {
|
1869
|
+
record.unloadRecord();
|
1870
|
+
}
|
1871
|
+
},
|
1872
|
+
|
1808
1873
|
/**
|
1809
1874
|
Takes a type and filter function, and returns a live RecordArray that
|
1810
1875
|
remains up to date as new records are loaded into the store or created
|
@@ -1821,14 +1886,6 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1821
1886
|
filter function will be invoked again to determine whether it should
|
1822
1887
|
still be in the array.
|
1823
1888
|
|
1824
|
-
Note that the existence of a filter on a type will trigger immediate
|
1825
|
-
materialization of all loaded data for a given type, so you might
|
1826
|
-
not want to use filters for a type if you are loading many records
|
1827
|
-
into the store, many of which are not active at any given time.
|
1828
|
-
|
1829
|
-
In this scenario, you might want to consider filtering the raw
|
1830
|
-
data before loading it into the store.
|
1831
|
-
|
1832
1889
|
@method filter
|
1833
1890
|
@param {Class} type
|
1834
1891
|
@param {Function} filter
|
@@ -1878,6 +1935,18 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1878
1935
|
return !get(this.recordForId(type, id), 'isEmpty');
|
1879
1936
|
},
|
1880
1937
|
|
1938
|
+
/**
|
1939
|
+
This method returns the metadata for a specific type.
|
1940
|
+
|
1941
|
+
@method metadataFor
|
1942
|
+
@param {string} type
|
1943
|
+
@return {object}
|
1944
|
+
*/
|
1945
|
+
metadataFor: function(type) {
|
1946
|
+
type = this.modelFor(type);
|
1947
|
+
return this.typeMapFor(type).metadata;
|
1948
|
+
},
|
1949
|
+
|
1881
1950
|
// ............
|
1882
1951
|
// . UPDATING .
|
1883
1952
|
// ............
|
@@ -1947,7 +2016,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1947
2016
|
|
1948
2017
|
forEach(pending, function(tuple) {
|
1949
2018
|
var record = tuple[0], resolver = tuple[1],
|
1950
|
-
adapter = this.
|
2019
|
+
adapter = this.adapterFor(record.constructor),
|
1951
2020
|
operation;
|
1952
2021
|
|
1953
2022
|
if (get(record, 'isNew')) {
|
@@ -1977,6 +2046,9 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
1977
2046
|
*/
|
1978
2047
|
didSaveRecord: function(record, data) {
|
1979
2048
|
if (data) {
|
2049
|
+
// normalize relationship IDs into records
|
2050
|
+
data = normalizeRelationships(this, record.constructor, data, record);
|
2051
|
+
|
1980
2052
|
this.updateId(record, data);
|
1981
2053
|
}
|
1982
2054
|
|
@@ -2069,7 +2141,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2069
2141
|
@param {DS.Model} type
|
2070
2142
|
@param {Object} data
|
2071
2143
|
@param {Boolean} partial the data should be merged into
|
2072
|
-
the existing
|
2144
|
+
the existing data, not replace it.
|
2073
2145
|
*/
|
2074
2146
|
_load: function(type, data, partial) {
|
2075
2147
|
var id = coerceId(data.id),
|
@@ -2086,20 +2158,23 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2086
2158
|
methods that take a type key (like `find`, `createRecord`,
|
2087
2159
|
etc.)
|
2088
2160
|
|
2089
|
-
@
|
2161
|
+
@method modelFor
|
2162
|
+
@param {String or subclass of DS.Model} key
|
2090
2163
|
@returns {subclass of DS.Model}
|
2091
2164
|
*/
|
2092
2165
|
modelFor: function(key) {
|
2093
|
-
|
2094
|
-
return key;
|
2095
|
-
}
|
2166
|
+
var factory;
|
2096
2167
|
|
2097
|
-
|
2168
|
+
if (typeof key === 'string') {
|
2169
|
+
factory = this.container.lookupFactory('model:' + key);
|
2098
2170
|
|
2171
|
+
factory.typeKey = key;
|
2172
|
+
} else {
|
2173
|
+
// A factory already supplied.
|
2174
|
+
factory = key;
|
2175
|
+
}
|
2099
2176
|
|
2100
2177
|
factory.store = this;
|
2101
|
-
factory.typeKey = key;
|
2102
|
-
|
2103
2178
|
return factory;
|
2104
2179
|
},
|
2105
2180
|
|
@@ -2169,7 +2244,7 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2169
2244
|
// If passed, it means that the data should be
|
2170
2245
|
// merged into the existing data, not replace it.
|
2171
2246
|
|
2172
|
-
|
2247
|
+
|
2173
2248
|
type = this.modelFor(type);
|
2174
2249
|
|
2175
2250
|
// normalize relationship IDs into records
|
@@ -2180,7 +2255,47 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2180
2255
|
return this.recordForId(type, data.id);
|
2181
2256
|
},
|
2182
2257
|
|
2258
|
+
/**
|
2259
|
+
Push some raw data into the store.
|
2260
|
+
|
2261
|
+
The data will be automatically deserialized using the
|
2262
|
+
serializer for the `type` param.
|
2263
|
+
|
2264
|
+
This method can be used both to push in brand new
|
2265
|
+
records, as well as to update existing records.
|
2266
|
+
|
2267
|
+
You can push in more than one type of object at once.
|
2268
|
+
All objects should be in the format expected by the
|
2269
|
+
serializer.
|
2270
|
+
|
2271
|
+
```js
|
2272
|
+
App.ApplicationSerializer = DS.ActiveModelSerializer;
|
2273
|
+
|
2274
|
+
var pushData = {
|
2275
|
+
posts: [
|
2276
|
+
{id: 1, post_title: "Great post", comment_ids: [2]}
|
2277
|
+
],
|
2278
|
+
comments: [
|
2279
|
+
{id: 2, comment_body: "Insightful comment"}
|
2280
|
+
]
|
2281
|
+
}
|
2282
|
+
|
2283
|
+
store.pushPayload('post', pushData);
|
2284
|
+
```
|
2285
|
+
|
2286
|
+
@method push
|
2287
|
+
@param {String} type
|
2288
|
+
@param {Object} payload
|
2289
|
+
*/
|
2290
|
+
|
2291
|
+
pushPayload: function (type, payload) {
|
2292
|
+
var serializer = this.serializerFor(type);
|
2293
|
+
serializer.pushPayload(this, payload);
|
2294
|
+
},
|
2295
|
+
|
2183
2296
|
update: function(type, data) {
|
2297
|
+
|
2298
|
+
|
2184
2299
|
return this.push(type, data, true);
|
2185
2300
|
},
|
2186
2301
|
|
@@ -2230,9 +2345,12 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2230
2345
|
idToRecord = typeMap.idToRecord;
|
2231
2346
|
|
2232
2347
|
|
2348
|
+
// lookupFactory should really return an object that creates
|
2349
|
+
// instances with the injections applied
|
2233
2350
|
var record = type._create({
|
2234
2351
|
id: id,
|
2235
2352
|
store: this,
|
2353
|
+
container: this.container
|
2236
2354
|
});
|
2237
2355
|
|
2238
2356
|
if (data) {
|
@@ -2335,12 +2453,12 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2335
2453
|
/**
|
2336
2454
|
Returns the adapter for a given type.
|
2337
2455
|
|
2338
|
-
@method
|
2456
|
+
@method adapterFor
|
2339
2457
|
@private
|
2340
2458
|
@param {subclass of DS.Model} type
|
2341
2459
|
@returns DS.Adapter
|
2342
2460
|
*/
|
2343
|
-
|
2461
|
+
adapterFor: function(type) {
|
2344
2462
|
var container = this.container, adapter;
|
2345
2463
|
|
2346
2464
|
if (container) {
|
@@ -2372,29 +2490,31 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
|
|
2372
2490
|
*/
|
2373
2491
|
serializerFor: function(type) {
|
2374
2492
|
type = this.modelFor(type);
|
2375
|
-
var adapter = this.
|
2493
|
+
var adapter = this.adapterFor(type);
|
2376
2494
|
|
2377
2495
|
return serializerFor(this.container, type.typeKey, adapter && adapter.defaultSerializer);
|
2378
2496
|
}
|
2379
2497
|
});
|
2380
2498
|
|
2381
|
-
function normalizeRelationships(store, type, data) {
|
2499
|
+
function normalizeRelationships(store, type, data, record) {
|
2382
2500
|
type.eachRelationship(function(key, relationship) {
|
2383
2501
|
// A link (usually a URL) was already provided in
|
2384
2502
|
// normalized form
|
2385
2503
|
if (data.links && data.links[key]) {
|
2504
|
+
if (record && relationship.options.async) { record._relationships[key] = null; }
|
2386
2505
|
return;
|
2387
2506
|
}
|
2388
2507
|
|
2389
|
-
var
|
2508
|
+
var kind = relationship.kind,
|
2390
2509
|
value = data[key];
|
2391
2510
|
|
2392
2511
|
if (value == null) { return; }
|
2393
2512
|
|
2394
|
-
if (
|
2513
|
+
if (kind === 'belongsTo') {
|
2395
2514
|
deserializeRecordId(store, data, key, relationship, value);
|
2396
|
-
} else if (
|
2515
|
+
} else if (kind === 'hasMany') {
|
2397
2516
|
deserializeRecordIds(store, data, key, relationship, value);
|
2517
|
+
addUnsavedRecords(record, key, value);
|
2398
2518
|
}
|
2399
2519
|
});
|
2400
2520
|
|
@@ -2419,7 +2539,7 @@ function deserializeRecordId(store, data, key, relationship, id) {
|
|
2419
2539
|
|
2420
2540
|
function typeFor(relationship, key, data) {
|
2421
2541
|
if (relationship.options.polymorphic) {
|
2422
|
-
return data[key + "
|
2542
|
+
return data[key + "Type"];
|
2423
2543
|
} else {
|
2424
2544
|
return relationship.type;
|
2425
2545
|
}
|
@@ -2431,6 +2551,14 @@ function deserializeRecordIds(store, data, key, relationship, ids) {
|
|
2431
2551
|
}
|
2432
2552
|
}
|
2433
2553
|
|
2554
|
+
// If there are any unsaved records that are in a hasMany they won't be
|
2555
|
+
// in the payload, so add them back in manually.
|
2556
|
+
function addUnsavedRecords(record, key, data) {
|
2557
|
+
if(record) {
|
2558
|
+
data.pushObjects(record.get(key).filterBy('isNew'));
|
2559
|
+
}
|
2560
|
+
}
|
2561
|
+
|
2434
2562
|
// Delegation to the adapter and promise management
|
2435
2563
|
|
2436
2564
|
DS.PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
|
@@ -2482,6 +2610,10 @@ function _find(adapter, store, type, id, resolver) {
|
|
2482
2610
|
payload = serializer.extract(store, type, payload, id, 'find');
|
2483
2611
|
|
2484
2612
|
return store.push(type, payload);
|
2613
|
+
}, function(error) {
|
2614
|
+
var record = store.getById(type, id);
|
2615
|
+
record.notFound();
|
2616
|
+
throw error;
|
2485
2617
|
}).then(resolver.resolve, resolver.reject);
|
2486
2618
|
}
|
2487
2619
|
|
@@ -2492,6 +2624,7 @@ function _findMany(adapter, store, type, ids, owner, resolver) {
|
|
2492
2624
|
return resolve(promise).then(function(payload) {
|
2493
2625
|
payload = serializer.extract(store, type, payload, null, 'findMany');
|
2494
2626
|
|
2627
|
+
|
2495
2628
|
store.pushMany(type, payload);
|
2496
2629
|
}).then(resolver.resolve, resolver.reject);
|
2497
2630
|
}
|
@@ -2503,11 +2636,25 @@ function _findHasMany(adapter, store, record, link, relationship, resolver) {
|
|
2503
2636
|
return resolve(promise).then(function(payload) {
|
2504
2637
|
payload = serializer.extract(store, relationship.type, payload, null, 'findHasMany');
|
2505
2638
|
|
2639
|
+
|
2506
2640
|
var records = store.pushMany(relationship.type, payload);
|
2507
2641
|
record.updateHasMany(relationship.key, records);
|
2508
2642
|
}).then(resolver.resolve, resolver.reject);
|
2509
2643
|
}
|
2510
2644
|
|
2645
|
+
function _findBelongsTo(adapter, store, record, link, relationship, resolver) {
|
2646
|
+
var promise = adapter.findBelongsTo(store, record, link, relationship),
|
2647
|
+
serializer = serializerForAdapter(adapter, relationship.type);
|
2648
|
+
|
2649
|
+
return resolve(promise).then(function(payload) {
|
2650
|
+
payload = serializer.extract(store, relationship.type, payload, null, 'findBelongsTo');
|
2651
|
+
|
2652
|
+
var record = store.push(relationship.type, payload);
|
2653
|
+
record.updateBelongsTo(relationship.key, record);
|
2654
|
+
return record;
|
2655
|
+
}).then(resolver.resolve, resolver.reject);
|
2656
|
+
}
|
2657
|
+
|
2511
2658
|
function _findAll(adapter, store, type, sinceToken, resolver) {
|
2512
2659
|
var promise = adapter.findAll(store, type, sinceToken),
|
2513
2660
|
serializer = serializerForAdapter(adapter, type);
|
@@ -2515,6 +2662,7 @@ function _findAll(adapter, store, type, sinceToken, resolver) {
|
|
2515
2662
|
return resolve(promise).then(function(payload) {
|
2516
2663
|
payload = serializer.extract(store, type, payload, null, 'findAll');
|
2517
2664
|
|
2665
|
+
|
2518
2666
|
store.pushMany(type, payload);
|
2519
2667
|
store.didUpdateAll(type);
|
2520
2668
|
return store.all(type);
|
@@ -2528,6 +2676,7 @@ function _findQuery(adapter, store, type, query, recordArray, resolver) {
|
|
2528
2676
|
return resolve(promise).then(function(payload) {
|
2529
2677
|
payload = serializer.extract(store, type, payload, null, 'findAll');
|
2530
2678
|
|
2679
|
+
|
2531
2680
|
recordArray.load(payload);
|
2532
2681
|
return recordArray;
|
2533
2682
|
}).then(resolver.resolve, resolver.reject);
|
@@ -2540,7 +2689,7 @@ function _commit(adapter, store, operation, record, resolver) {
|
|
2540
2689
|
|
2541
2690
|
|
2542
2691
|
return promise.then(function(payload) {
|
2543
|
-
payload = serializer.extract(store, type, payload, get(record, 'id'), operation);
|
2692
|
+
if (payload) { payload = serializer.extract(store, type, payload, get(record, 'id'), operation); }
|
2544
2693
|
store.didSaveRecord(record, payload);
|
2545
2694
|
return record;
|
2546
2695
|
}, function(reason) {
|
@@ -2563,8 +2712,7 @@ function _commit(adapter, store, operation, record, resolver) {
|
|
2563
2712
|
@module ember-data
|
2564
2713
|
*/
|
2565
2714
|
|
2566
|
-
var get = Ember.get, set = Ember.set
|
2567
|
-
once = Ember.run.once, arrayMap = Ember.ArrayPolyfills.map;
|
2715
|
+
var get = Ember.get, set = Ember.set;
|
2568
2716
|
|
2569
2717
|
/*
|
2570
2718
|
WARNING: Much of these docs are inaccurate as of bf8497.
|
@@ -2732,10 +2880,14 @@ var hasDefinedProperties = function(object) {
|
|
2732
2880
|
};
|
2733
2881
|
|
2734
2882
|
var didSetProperty = function(record, context) {
|
2735
|
-
if (context.value
|
2883
|
+
if (context.value === context.originalValue) {
|
2884
|
+
delete record._attributes[context.name];
|
2885
|
+
record.send('propertyWasReset', context.name);
|
2886
|
+
} else if (context.value !== context.oldValue) {
|
2736
2887
|
record.send('becomeDirty');
|
2737
|
-
record.updateRecordArraysLater();
|
2738
2888
|
}
|
2889
|
+
|
2890
|
+
record.updateRecordArraysLater();
|
2739
2891
|
};
|
2740
2892
|
|
2741
2893
|
// Implementation notes:
|
@@ -2793,10 +2945,20 @@ var DirtyState = {
|
|
2793
2945
|
// This means that there are local pending changes, but they
|
2794
2946
|
// have not yet begun to be saved, and are not invalid.
|
2795
2947
|
uncommitted: {
|
2796
|
-
|
2797
2948
|
// EVENTS
|
2798
2949
|
didSetProperty: didSetProperty,
|
2799
2950
|
|
2951
|
+
propertyWasReset: function(record, name) {
|
2952
|
+
var stillDirty = false;
|
2953
|
+
|
2954
|
+
for (var prop in record._attributes) {
|
2955
|
+
stillDirty = true;
|
2956
|
+
break;
|
2957
|
+
}
|
2958
|
+
|
2959
|
+
if (!stillDirty) { record.send('rolledBack'); }
|
2960
|
+
},
|
2961
|
+
|
2800
2962
|
pushedData: Ember.K,
|
2801
2963
|
|
2802
2964
|
becomeDirty: Ember.K,
|
@@ -2981,6 +3143,8 @@ var RootState = {
|
|
2981
3143
|
// you out of the in-flight state.
|
2982
3144
|
rolledBack: Ember.K,
|
2983
3145
|
|
3146
|
+
propertyWasReset: Ember.K,
|
3147
|
+
|
2984
3148
|
// SUBSTATES
|
2985
3149
|
|
2986
3150
|
// A record begins its lifecycle in the `empty` state.
|
@@ -2992,7 +3156,8 @@ var RootState = {
|
|
2992
3156
|
isEmpty: true,
|
2993
3157
|
|
2994
3158
|
// EVENTS
|
2995
|
-
loadingData: function(record) {
|
3159
|
+
loadingData: function(record, promise) {
|
3160
|
+
record._loadingPromise = promise;
|
2996
3161
|
record.transitionTo('loading');
|
2997
3162
|
},
|
2998
3163
|
|
@@ -3006,6 +3171,7 @@ var RootState = {
|
|
3006
3171
|
|
3007
3172
|
pushedData: function(record) {
|
3008
3173
|
record.transitionTo('loaded.saved');
|
3174
|
+
record.triggerLater('didLoad');
|
3009
3175
|
}
|
3010
3176
|
},
|
3011
3177
|
|
@@ -3019,6 +3185,10 @@ var RootState = {
|
|
3019
3185
|
// FLAGS
|
3020
3186
|
isLoading: true,
|
3021
3187
|
|
3188
|
+
exit: function(record) {
|
3189
|
+
record._loadingPromise = null;
|
3190
|
+
},
|
3191
|
+
|
3022
3192
|
// EVENTS
|
3023
3193
|
pushedData: function(record) {
|
3024
3194
|
record.transitionTo('loaded.saved');
|
@@ -3028,6 +3198,10 @@ var RootState = {
|
|
3028
3198
|
|
3029
3199
|
becameError: function(record) {
|
3030
3200
|
record.triggerLater('becameError', record);
|
3201
|
+
},
|
3202
|
+
|
3203
|
+
notFound: function(record) {
|
3204
|
+
record.transitionTo('empty');
|
3031
3205
|
}
|
3032
3206
|
},
|
3033
3207
|
|
@@ -3092,7 +3266,7 @@ var RootState = {
|
|
3092
3266
|
|
3093
3267
|
didCommit: function(record) {
|
3094
3268
|
record.send('invokeLifecycleCallbacks', get(record, 'lastDirtyType'));
|
3095
|
-
}
|
3269
|
+
}
|
3096
3270
|
|
3097
3271
|
},
|
3098
3272
|
|
@@ -3203,8 +3377,6 @@ var RootState = {
|
|
3203
3377
|
}
|
3204
3378
|
};
|
3205
3379
|
|
3206
|
-
var hasOwnProp = {}.hasOwnProperty;
|
3207
|
-
|
3208
3380
|
function wireState(object, parent, name) {
|
3209
3381
|
/*jshint proto:true*/
|
3210
3382
|
// TODO: Use Object.create and copy instead
|
@@ -3235,11 +3407,9 @@ DS.RootState = RootState;
|
|
3235
3407
|
@module ember-data
|
3236
3408
|
*/
|
3237
3409
|
|
3238
|
-
var get = Ember.get, set = Ember.set,
|
3410
|
+
var get = Ember.get, set = Ember.set,
|
3239
3411
|
merge = Ember.merge, once = Ember.run.once;
|
3240
3412
|
|
3241
|
-
var arrayMap = Ember.ArrayPolyfills.map;
|
3242
|
-
|
3243
3413
|
var retrieveFromCurrentState = Ember.computed(function(key, value) {
|
3244
3414
|
return get(get(this, 'currentState'), key);
|
3245
3415
|
}).property('currentState').readOnly();
|
@@ -3303,7 +3473,8 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3303
3473
|
@returns {Object} A JSON representation of the object.
|
3304
3474
|
*/
|
3305
3475
|
toJSON: function(options) {
|
3306
|
-
|
3476
|
+
// container is for lazy transform lookups
|
3477
|
+
var serializer = DS.JSONSerializer.create({ container: this.container });
|
3307
3478
|
return serializer.serialize(this, options);
|
3308
3479
|
},
|
3309
3480
|
|
@@ -3421,6 +3592,8 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3421
3592
|
for (i=0, l=setups.length; i<l; i++) {
|
3422
3593
|
setups[i].setup(this);
|
3423
3594
|
}
|
3595
|
+
|
3596
|
+
this.updateRecordArraysLater();
|
3424
3597
|
},
|
3425
3598
|
|
3426
3599
|
_unhandledEvent: function(state, name, context) {
|
@@ -3440,22 +3613,45 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3440
3613
|
if (transaction) { fn(transaction); }
|
3441
3614
|
},
|
3442
3615
|
|
3443
|
-
loadingData: function() {
|
3444
|
-
this.send('loadingData');
|
3616
|
+
loadingData: function(promise) {
|
3617
|
+
this.send('loadingData', promise);
|
3445
3618
|
},
|
3446
3619
|
|
3447
3620
|
loadedData: function() {
|
3448
3621
|
this.send('loadedData');
|
3449
3622
|
},
|
3450
3623
|
|
3624
|
+
notFound: function() {
|
3625
|
+
this.send('notFound');
|
3626
|
+
},
|
3627
|
+
|
3451
3628
|
pushedData: function() {
|
3452
3629
|
this.send('pushedData');
|
3453
3630
|
},
|
3454
3631
|
|
3632
|
+
/**
|
3633
|
+
Marks the record as deleted but does not save it. You must call
|
3634
|
+
`save` afterwards if you want to persist it. You might use this
|
3635
|
+
method if you want to allow the user to still `rollback()` a
|
3636
|
+
delete after it was made.
|
3637
|
+
|
3638
|
+
@method deleteRecord
|
3639
|
+
*/
|
3455
3640
|
deleteRecord: function() {
|
3456
3641
|
this.send('deleteRecord');
|
3457
3642
|
},
|
3458
3643
|
|
3644
|
+
/**
|
3645
|
+
Same as `deleteRecord`, but saves the record immediately.
|
3646
|
+
|
3647
|
+
@method destroyRecord
|
3648
|
+
@returns Promise
|
3649
|
+
*/
|
3650
|
+
destroyRecord: function() {
|
3651
|
+
this.deleteRecord();
|
3652
|
+
return this.save();
|
3653
|
+
},
|
3654
|
+
|
3459
3655
|
unloadRecord: function() {
|
3460
3656
|
|
3461
3657
|
|
@@ -3480,6 +3676,27 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3480
3676
|
}
|
3481
3677
|
},
|
3482
3678
|
|
3679
|
+
/**
|
3680
|
+
Gets the diff for the current model.
|
3681
|
+
|
3682
|
+
@method changedAttributes
|
3683
|
+
|
3684
|
+
@returns {Object} an object, whose keys are changed properties,
|
3685
|
+
and value is an [oldProp, newProp] array.
|
3686
|
+
*/
|
3687
|
+
changedAttributes: function() {
|
3688
|
+
var oldData = get(this, '_data'),
|
3689
|
+
newData = get(this, '_attributes'),
|
3690
|
+
diffData = {},
|
3691
|
+
prop;
|
3692
|
+
|
3693
|
+
for (prop in newData) {
|
3694
|
+
diffData[prop] = [oldData[prop], newData[prop]];
|
3695
|
+
}
|
3696
|
+
|
3697
|
+
return diffData;
|
3698
|
+
},
|
3699
|
+
|
3483
3700
|
adapterWillCommit: function() {
|
3484
3701
|
this.send('willCommit');
|
3485
3702
|
},
|
@@ -3525,6 +3742,7 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3525
3742
|
var relationships = get(this.constructor, 'relationshipsByName');
|
3526
3743
|
this.updateRecordArraysLater();
|
3527
3744
|
relationships.forEach(function(name, relationship) {
|
3745
|
+
if (this._data.links && this._data.links[name]) { return; }
|
3528
3746
|
if (relationship.kind === 'hasMany') {
|
3529
3747
|
this.hasManyDidChange(relationship.key);
|
3530
3748
|
}
|
@@ -3535,8 +3753,6 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3535
3753
|
var hasMany = this._relationships[key];
|
3536
3754
|
|
3537
3755
|
if (hasMany) {
|
3538
|
-
var type = get(this.constructor, 'relationshipsByName').get(key).type;
|
3539
|
-
var store = get(this, 'store');
|
3540
3756
|
var records = this._data[key] || [];
|
3541
3757
|
|
3542
3758
|
set(hasMany, 'content', Ember.A(records));
|
@@ -3559,6 +3775,7 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3559
3775
|
var relationships = this._relationships;
|
3560
3776
|
|
3561
3777
|
this.eachRelationship(function(name, rel) {
|
3778
|
+
if (data.links && data.links[name]) { return; }
|
3562
3779
|
if (rel.options.async) { relationships[name] = null; }
|
3563
3780
|
});
|
3564
3781
|
|
@@ -3587,8 +3804,18 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3587
3804
|
this.hasManyDidChange(name);
|
3588
3805
|
},
|
3589
3806
|
|
3807
|
+
updateBelongsTo: function(name, record) {
|
3808
|
+
this._data[name] = record;
|
3809
|
+
},
|
3810
|
+
|
3590
3811
|
rollback: function() {
|
3591
3812
|
this._attributes = {};
|
3813
|
+
|
3814
|
+
if (get(this, 'isError')) {
|
3815
|
+
this._inFlightAttributes = {};
|
3816
|
+
set(this, 'isError', false);
|
3817
|
+
}
|
3818
|
+
|
3592
3819
|
this.send('rolledBack');
|
3593
3820
|
|
3594
3821
|
this.suspendRelationshipObservers(function() {
|
@@ -3639,7 +3866,7 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
|
|
3639
3866
|
@method save
|
3640
3867
|
*/
|
3641
3868
|
save: function() {
|
3642
|
-
var resolver = Ember.RSVP.defer()
|
3869
|
+
var resolver = Ember.RSVP.defer();
|
3643
3870
|
|
3644
3871
|
this.get('store').scheduleSave(this, resolver);
|
3645
3872
|
this._inFlightAttributes = this._attributes;
|
@@ -3871,12 +4098,11 @@ DS.attr = function(type, options) {
|
|
3871
4098
|
options: options
|
3872
4099
|
};
|
3873
4100
|
|
3874
|
-
return Ember.computed(function(key, value
|
3875
|
-
var currentValue;
|
3876
|
-
|
4101
|
+
return Ember.computed(function(key, value) {
|
3877
4102
|
if (arguments.length > 1) {
|
3878
4103
|
|
3879
|
-
|
4104
|
+
var oldValue = this._attributes[key] || this._inFlightAttributes[key] || this._data[key];
|
4105
|
+
this.send('didSetProperty', { name: key, oldValue: oldValue, originalValue: this._data[key], value: value });
|
3880
4106
|
this._attributes[key] = value;
|
3881
4107
|
return value;
|
3882
4108
|
} else if (hasValue(this, key)) {
|
@@ -4429,18 +4655,23 @@ var get = Ember.get, set = Ember.set,
|
|
4429
4655
|
function asyncBelongsTo(type, options, meta) {
|
4430
4656
|
return Ember.computed(function(key, value) {
|
4431
4657
|
var data = get(this, 'data'),
|
4432
|
-
store = get(this, 'store')
|
4433
|
-
belongsTo;
|
4658
|
+
store = get(this, 'store');
|
4434
4659
|
|
4435
4660
|
if (arguments.length === 2) {
|
4436
4661
|
|
4437
|
-
return value === undefined ? null : value;
|
4662
|
+
return value === undefined ? null : DS.PromiseObject.create({ promise: Ember.RSVP.resolve(value) });
|
4438
4663
|
}
|
4439
4664
|
|
4440
|
-
|
4665
|
+
var link = data.links && data.links[key],
|
4666
|
+
belongsTo = data[key];
|
4441
4667
|
|
4442
|
-
if(!isNone(belongsTo)
|
4443
|
-
|
4668
|
+
if(!isNone(belongsTo)) {
|
4669
|
+
var promise = store.fetchRecord(belongsTo) || Ember.RSVP.resolve(belongsTo);
|
4670
|
+
return DS.PromiseObject.create({promise: promise});
|
4671
|
+
} else if (link) {
|
4672
|
+
var resolver = Ember.RSVP.defer();
|
4673
|
+
store.findBelongsTo(this, link, meta, resolver);
|
4674
|
+
return DS.PromiseObject.create({ promise: resolver.promise });
|
4444
4675
|
} else {
|
4445
4676
|
return null;
|
4446
4677
|
}
|
@@ -4448,7 +4679,12 @@ function asyncBelongsTo(type, options, meta) {
|
|
4448
4679
|
}
|
4449
4680
|
|
4450
4681
|
DS.belongsTo = function(type, options) {
|
4682
|
+
if (typeof type === 'object') {
|
4683
|
+
options = type;
|
4684
|
+
type = undefined;
|
4685
|
+
} else {
|
4451
4686
|
|
4687
|
+
}
|
4452
4688
|
|
4453
4689
|
options = options || {};
|
4454
4690
|
|
@@ -4463,11 +4699,7 @@ DS.belongsTo = function(type, options) {
|
|
4463
4699
|
store = get(this, 'store'), belongsTo, typeClass;
|
4464
4700
|
|
4465
4701
|
if (typeof type === 'string') {
|
4466
|
-
|
4467
|
-
typeClass = store.modelFor(type);
|
4468
|
-
} else {
|
4469
|
-
typeClass = get(Ember.lookup, type);
|
4470
|
-
}
|
4702
|
+
typeClass = store.modelFor(type);
|
4471
4703
|
} else {
|
4472
4704
|
typeClass = type;
|
4473
4705
|
}
|
@@ -4481,9 +4713,7 @@ DS.belongsTo = function(type, options) {
|
|
4481
4713
|
|
4482
4714
|
if (isNone(belongsTo)) { return null; }
|
4483
4715
|
|
4484
|
-
|
4485
|
-
store.fetchRecord(belongsTo);
|
4486
|
-
}
|
4716
|
+
store.fetchRecord(belongsTo);
|
4487
4717
|
|
4488
4718
|
return belongsTo;
|
4489
4719
|
}).property('data').meta(meta);
|
@@ -4507,11 +4737,12 @@ DS.Model.reopen({
|
|
4507
4737
|
*/
|
4508
4738
|
belongsToWillChange: Ember.beforeObserver(function(record, key) {
|
4509
4739
|
if (get(record, 'isLoaded')) {
|
4510
|
-
var oldParent = get(record, key)
|
4511
|
-
|
4740
|
+
var oldParent = get(record, key);
|
4741
|
+
|
4742
|
+
if (oldParent) {
|
4743
|
+
var store = get(record, 'store'),
|
4744
|
+
change = DS.RelationshipChange.createChange(record, oldParent, store, { key: key, kind: "belongsTo", changeType: "remove" });
|
4512
4745
|
|
4513
|
-
if (oldParent){
|
4514
|
-
var change = DS.RelationshipChange.createChange(record, oldParent, store, { key: key, kind: "belongsTo", changeType: "remove" });
|
4515
4746
|
change.sync();
|
4516
4747
|
this._changesToSync[key] = change;
|
4517
4748
|
}
|
@@ -4528,7 +4759,8 @@ DS.Model.reopen({
|
|
4528
4759
|
belongsToDidChange: Ember.immediateObserver(function(record, key) {
|
4529
4760
|
if (get(record, 'isLoaded')) {
|
4530
4761
|
var newParent = get(record, key);
|
4531
|
-
|
4762
|
+
|
4763
|
+
if (newParent) {
|
4532
4764
|
var store = get(record, 'store'),
|
4533
4765
|
change = DS.RelationshipChange.createChange(record, newParent, store, { key: key, kind: "belongsTo", changeType: "add" });
|
4534
4766
|
|
@@ -4550,10 +4782,11 @@ DS.Model.reopen({
|
|
4550
4782
|
*/
|
4551
4783
|
|
4552
4784
|
var get = Ember.get, set = Ember.set, setProperties = Ember.setProperties;
|
4553
|
-
var forEach = Ember.EnumerableUtils.forEach;
|
4554
4785
|
|
4555
4786
|
function asyncHasMany(type, options, meta) {
|
4556
4787
|
return Ember.computed(function(key, value) {
|
4788
|
+
if (this._relationships[key]) { return this._relationships[key]; }
|
4789
|
+
|
4557
4790
|
var resolver = Ember.RSVP.defer();
|
4558
4791
|
|
4559
4792
|
var relationship = buildRelationship(this, key, options, function(store, data) {
|
@@ -4608,7 +4841,10 @@ function hasRelationship(type, options) {
|
|
4608
4841
|
}
|
4609
4842
|
|
4610
4843
|
DS.hasMany = function(type, options) {
|
4611
|
-
|
4844
|
+
if (typeof type === 'object') {
|
4845
|
+
options = type;
|
4846
|
+
type = undefined;
|
4847
|
+
}
|
4612
4848
|
return hasRelationship(type, options);
|
4613
4849
|
};
|
4614
4850
|
|
@@ -4647,7 +4883,7 @@ DS.Model.reopen({
|
|
4647
4883
|
being defined. So, for example, when the user does this:
|
4648
4884
|
|
4649
4885
|
DS.Model.extend({
|
4650
|
-
parent: DS.belongsTo(
|
4886
|
+
parent: DS.belongsTo('user')
|
4651
4887
|
});
|
4652
4888
|
|
4653
4889
|
This hook would be called with "parent" as the key and the computed
|
@@ -4701,7 +4937,7 @@ DS.Model.reopenClass({
|
|
4701
4937
|
For example, if you define a model like this:
|
4702
4938
|
|
4703
4939
|
App.Post = DS.Model.extend({
|
4704
|
-
comments: DS.hasMany(
|
4940
|
+
comments: DS.hasMany('comment')
|
4705
4941
|
});
|
4706
4942
|
|
4707
4943
|
Calling `App.Post.typeForRelationship('comments')` will return `App.Comment`.
|
@@ -4774,9 +5010,9 @@ DS.Model.reopenClass({
|
|
4774
5010
|
For example, given the following model definition:
|
4775
5011
|
|
4776
5012
|
App.Blog = DS.Model.extend({
|
4777
|
-
users: DS.hasMany(
|
4778
|
-
owner: DS.belongsTo(
|
4779
|
-
posts: DS.hasMany(
|
5013
|
+
users: DS.hasMany('user'),
|
5014
|
+
owner: DS.belongsTo('user'),
|
5015
|
+
posts: DS.hasMany('post')
|
4780
5016
|
});
|
4781
5017
|
|
4782
5018
|
This computed property would return a map describing these
|
@@ -4806,7 +5042,7 @@ DS.Model.reopenClass({
|
|
4806
5042
|
// it to the map.
|
4807
5043
|
if (meta.isRelationship) {
|
4808
5044
|
if (typeof meta.type === 'string') {
|
4809
|
-
meta.type =
|
5045
|
+
meta.type = this.store.modelFor(meta.type);
|
4810
5046
|
}
|
4811
5047
|
|
4812
5048
|
var relationshipsForType = map.get(meta.type);
|
@@ -4824,10 +5060,10 @@ DS.Model.reopenClass({
|
|
4824
5060
|
definition:
|
4825
5061
|
|
4826
5062
|
App.Blog = DS.Model.extend({
|
4827
|
-
users: DS.hasMany(
|
4828
|
-
owner: DS.belongsTo(
|
5063
|
+
users: DS.hasMany('user'),
|
5064
|
+
owner: DS.belongsTo('user'),
|
4829
5065
|
|
4830
|
-
posts: DS.hasMany(
|
5066
|
+
posts: DS.hasMany('post')
|
4831
5067
|
});
|
4832
5068
|
|
4833
5069
|
This property would contain the following:
|
@@ -4863,9 +5099,10 @@ DS.Model.reopenClass({
|
|
4863
5099
|
For example, given a model with this definition:
|
4864
5100
|
|
4865
5101
|
App.Blog = DS.Model.extend({
|
4866
|
-
users: DS.hasMany(
|
4867
|
-
owner: DS.belongsTo(
|
4868
|
-
|
5102
|
+
users: DS.hasMany('user'),
|
5103
|
+
owner: DS.belongsTo('user'),
|
5104
|
+
|
5105
|
+
posts: DS.hasMany('post')
|
4869
5106
|
});
|
4870
5107
|
|
4871
5108
|
This property would contain the following:
|
@@ -4890,7 +5127,7 @@ DS.Model.reopenClass({
|
|
4890
5127
|
type = meta.type;
|
4891
5128
|
|
4892
5129
|
if (typeof type === 'string') {
|
4893
|
-
type = get(this, type, false) ||
|
5130
|
+
type = get(this, type, false) || this.store.modelFor(type);
|
4894
5131
|
}
|
4895
5132
|
|
4896
5133
|
|
@@ -4912,10 +5149,10 @@ DS.Model.reopenClass({
|
|
4912
5149
|
definition:
|
4913
5150
|
|
4914
5151
|
App.Blog = DS.Model.extend({
|
4915
|
-
users: DS.hasMany(
|
4916
|
-
owner: DS.belongsTo(
|
5152
|
+
users: DS.hasMany('user'),
|
5153
|
+
owner: DS.belongsTo('user'),
|
4917
5154
|
|
4918
|
-
posts: DS.hasMany(
|
5155
|
+
posts: DS.hasMany('post')
|
4919
5156
|
});
|
4920
5157
|
|
4921
5158
|
This property would contain the following:
|
@@ -4939,6 +5176,12 @@ DS.Model.reopenClass({
|
|
4939
5176
|
meta.key = name;
|
4940
5177
|
type = meta.type;
|
4941
5178
|
|
5179
|
+
if (!type && meta.kind === 'hasMany') {
|
5180
|
+
type = Ember.String.singularize(name);
|
5181
|
+
} else if (!type) {
|
5182
|
+
type = name;
|
5183
|
+
}
|
5184
|
+
|
4942
5185
|
if (typeof type === 'string') {
|
4943
5186
|
meta.type = this.store.modelFor(type);
|
4944
5187
|
}
|
@@ -4958,10 +5201,10 @@ DS.Model.reopenClass({
|
|
4958
5201
|
For example:
|
4959
5202
|
|
4960
5203
|
App.Blog = DS.Model.extend({
|
4961
|
-
users: DS.hasMany(
|
4962
|
-
owner: DS.belongsTo(
|
5204
|
+
users: DS.hasMany('user'),
|
5205
|
+
owner: DS.belongsTo('user'),
|
4963
5206
|
|
4964
|
-
posts: DS.hasMany(
|
5207
|
+
posts: DS.hasMany('post'),
|
4965
5208
|
|
4966
5209
|
title: DS.attr('string')
|
4967
5210
|
});
|
@@ -5267,9 +5510,8 @@ DS.RecordArrayManager = Ember.Object.extend({
|
|
5267
5510
|
@module ember-data
|
5268
5511
|
*/
|
5269
5512
|
|
5270
|
-
var get = Ember.get, set = Ember.set
|
5513
|
+
var get = Ember.get, set = Ember.set;
|
5271
5514
|
var map = Ember.ArrayPolyfills.map;
|
5272
|
-
var resolve = Ember.RSVP.resolve;
|
5273
5515
|
|
5274
5516
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
5275
5517
|
|
@@ -5283,18 +5525,6 @@ DS.InvalidError = function(errors) {
|
|
5283
5525
|
};
|
5284
5526
|
DS.InvalidError.prototype = Ember.create(Error.prototype);
|
5285
5527
|
|
5286
|
-
function isThenable(object) {
|
5287
|
-
return object && typeof object.then === 'function';
|
5288
|
-
}
|
5289
|
-
|
5290
|
-
// Simple dispatcher to support overriding the aliased
|
5291
|
-
// method in subclasses.
|
5292
|
-
function aliasMethod(methodName) {
|
5293
|
-
return function() {
|
5294
|
-
return this[methodName].apply(this, arguments);
|
5295
|
-
};
|
5296
|
-
}
|
5297
|
-
|
5298
5528
|
/**
|
5299
5529
|
An adapter is an object that receives requests from a store and
|
5300
5530
|
translates them into the appropriate action to take against your
|
@@ -5348,8 +5578,8 @@ DS.Adapter = Ember.Object.extend(DS._Mappable, {
|
|
5348
5578
|
The `find()` method is invoked when the store is asked for a record that
|
5349
5579
|
has not previously been loaded. In response to `find()` being called, you
|
5350
5580
|
should query your persistence layer for a record with the given ID. Once
|
5351
|
-
found, you can asynchronously call the store's `
|
5352
|
-
the record.
|
5581
|
+
found, you can asynchronously call the store's `push()` method to push
|
5582
|
+
the record into the store.
|
5353
5583
|
|
5354
5584
|
Here is an example `find` implementation:
|
5355
5585
|
|
@@ -5360,8 +5590,8 @@ DS.Adapter = Ember.Object.extend(DS._Mappable, {
|
|
5360
5590
|
jQuery.getJSON(url, function(data) {
|
5361
5591
|
// data is a hash of key/value pairs. If your server returns a
|
5362
5592
|
// root, simply do something like:
|
5363
|
-
// store.
|
5364
|
-
store.
|
5593
|
+
// store.push(type, id, data.person)
|
5594
|
+
store.push(type, id, data);
|
5365
5595
|
});
|
5366
5596
|
}
|
5367
5597
|
|
@@ -5436,9 +5666,9 @@ DS.Adapter = Ember.Object.extend(DS._Mappable, {
|
|
5436
5666
|
method on success or `didError` method on failure.
|
5437
5667
|
|
5438
5668
|
@method createRecord
|
5439
|
-
@
|
5440
|
-
@
|
5441
|
-
@
|
5669
|
+
@param {DS.Store} store
|
5670
|
+
@param {subclass of DS.Model} type the DS.Model class of the record
|
5671
|
+
@param {DS.Model} record
|
5442
5672
|
*/
|
5443
5673
|
createRecord: Ember.required(Function),
|
5444
5674
|
|
@@ -5449,9 +5679,9 @@ DS.Adapter = Ember.Object.extend(DS._Mappable, {
|
|
5449
5679
|
Serializes the record update and send it to the server.
|
5450
5680
|
|
5451
5681
|
@method updateRecord
|
5452
|
-
@
|
5453
|
-
@
|
5454
|
-
@
|
5682
|
+
@param {DS.Store} store
|
5683
|
+
@param {subclass of DS.Model} type the DS.Model class of the record
|
5684
|
+
@param {DS.Model} record
|
5455
5685
|
*/
|
5456
5686
|
updateRecord: Ember.required(Function),
|
5457
5687
|
|
@@ -5462,9 +5692,9 @@ DS.Adapter = Ember.Object.extend(DS._Mappable, {
|
|
5462
5692
|
Sends a delete request for the record to the server.
|
5463
5693
|
|
5464
5694
|
@method deleteRecord
|
5465
|
-
@
|
5466
|
-
@
|
5467
|
-
@
|
5695
|
+
@param {DS.Store} store
|
5696
|
+
@param {subclass of DS.Model} type the DS.Model class of the record
|
5697
|
+
@param {DS.Model} record
|
5468
5698
|
*/
|
5469
5699
|
deleteRecord: Ember.required(Function),
|
5470
5700
|
|
@@ -5476,9 +5706,9 @@ DS.Adapter = Ember.Object.extend(DS._Mappable, {
|
|
5476
5706
|
server requests.
|
5477
5707
|
|
5478
5708
|
@method findMany
|
5479
|
-
@
|
5480
|
-
@
|
5481
|
-
@
|
5709
|
+
@param {DS.Store} store
|
5710
|
+
@param {subclass of DS.Model} type the DS.Model class of the records
|
5711
|
+
@param {Array} ids
|
5482
5712
|
*/
|
5483
5713
|
findMany: function(store, type, ids) {
|
5484
5714
|
var promises = map.call(ids, function(id) {
|
@@ -5575,7 +5805,7 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|
5575
5805
|
},
|
5576
5806
|
|
5577
5807
|
/**
|
5578
|
-
Implement this method in order to provide
|
5808
|
+
Implement this method in order to provide json for CRUD methods
|
5579
5809
|
|
5580
5810
|
@method mockJSON
|
5581
5811
|
@param type
|
@@ -5591,7 +5821,7 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|
5591
5821
|
@param record
|
5592
5822
|
*/
|
5593
5823
|
generateIdForRecord: function(store) {
|
5594
|
-
return counter++;
|
5824
|
+
return "fixture-" + counter++;
|
5595
5825
|
},
|
5596
5826
|
|
5597
5827
|
/**
|
@@ -5803,6 +6033,7 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|
5803
6033
|
|
5804
6034
|
var get = Ember.get, set = Ember.set;
|
5805
6035
|
var forEach = Ember.ArrayPolyfills.forEach;
|
6036
|
+
var map = Ember.ArrayPolyfills.map;
|
5806
6037
|
|
5807
6038
|
function coerceId(id) {
|
5808
6039
|
return id == null ? null : id+'';
|
@@ -5843,6 +6074,10 @@ function coerceId(id) {
|
|
5843
6074
|
You can also implement `keyForRelationship`, which takes the name
|
5844
6075
|
of the relationship as the first parameter, and the kind of
|
5845
6076
|
relationship (`hasMany` or `belongsTo`) as the second parameter.
|
6077
|
+
|
6078
|
+
@class RESTSerializer
|
6079
|
+
@namespace DS
|
6080
|
+
@extends DS.JSONSerializer
|
5846
6081
|
*/
|
5847
6082
|
DS.RESTSerializer = DS.JSONSerializer.extend({
|
5848
6083
|
/**
|
@@ -5922,6 +6157,31 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
5922
6157
|
return this._super(type, hash, prop);
|
5923
6158
|
},
|
5924
6159
|
|
6160
|
+
/**
|
6161
|
+
You can use this method to normalize all payloads, regardless of whether they
|
6162
|
+
represent single records or an array.
|
6163
|
+
|
6164
|
+
For example, you might want to remove some extraneous data from the payload:
|
6165
|
+
|
6166
|
+
```js
|
6167
|
+
App.ApplicationSerializer = DS.RESTSerializer.extend({
|
6168
|
+
normalizePayload: function(type, payload) {
|
6169
|
+
delete payload.version;
|
6170
|
+
delete payload.status;
|
6171
|
+
return payload;
|
6172
|
+
}
|
6173
|
+
});
|
6174
|
+
```
|
6175
|
+
|
6176
|
+
@method normalizePayload
|
6177
|
+
@param {subclass of DS.Model} type
|
6178
|
+
@param {Object} hash
|
6179
|
+
@returns Object the normalized payload
|
6180
|
+
*/
|
6181
|
+
normalizePayload: function(type, payload) {
|
6182
|
+
return payload;
|
6183
|
+
},
|
6184
|
+
|
5925
6185
|
/**
|
5926
6186
|
@method normalizeId
|
5927
6187
|
@private
|
@@ -6057,6 +6317,7 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
6057
6317
|
for the first time or updated (`createRecord` or `updateRecord`). In
|
6058
6318
|
particular, it will update the properties of the record that was saved.
|
6059
6319
|
|
6320
|
+
@method extractSingle
|
6060
6321
|
@param {DS.Store} store
|
6061
6322
|
@param {subclass of DS.Model} type
|
6062
6323
|
@param {Object} payload
|
@@ -6065,25 +6326,33 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
6065
6326
|
@returns Object the primary response to the original request
|
6066
6327
|
*/
|
6067
6328
|
extractSingle: function(store, primaryType, payload, recordId, requestType) {
|
6329
|
+
payload = this.normalizePayload(primaryType, payload);
|
6330
|
+
|
6068
6331
|
var primaryTypeName = primaryType.typeKey,
|
6069
6332
|
primaryRecord;
|
6070
6333
|
|
6071
6334
|
for (var prop in payload) {
|
6072
|
-
|
6073
|
-
|
6335
|
+
var typeName = this.typeForRoot(prop),
|
6336
|
+
isPrimary = typeName === primaryTypeName;
|
6337
|
+
|
6338
|
+
// legacy support for singular resources
|
6339
|
+
if (isPrimary && Ember.typeOf(payload[prop]) !== "array" ) {
|
6074
6340
|
primaryRecord = this.normalize(primaryType, payload[prop], prop);
|
6075
6341
|
continue;
|
6076
6342
|
}
|
6077
6343
|
|
6078
|
-
var
|
6079
|
-
type = store.modelFor(typeName);
|
6344
|
+
var type = store.modelFor(typeName);
|
6080
6345
|
|
6081
6346
|
/*jshint loopfunc:true*/
|
6082
6347
|
forEach.call(payload[prop], function(hash) {
|
6083
|
-
|
6348
|
+
var typeName = this.typeForRoot(prop),
|
6349
|
+
type = store.modelFor(typeName),
|
6350
|
+
typeSerializer = store.serializerFor(type);
|
6084
6351
|
|
6085
|
-
|
6086
|
-
|
6352
|
+
hash = typeSerializer.normalize(type, hash, prop);
|
6353
|
+
|
6354
|
+
var isFirstCreatedRecord = isPrimary && !recordId && !primaryRecord,
|
6355
|
+
isUpdatedRecord = isPrimary && coerceId(hash.id) === recordId;
|
6087
6356
|
|
6088
6357
|
// find the primary record.
|
6089
6358
|
//
|
@@ -6190,6 +6459,12 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
6190
6459
|
or `findHasMany`. In particular, the primary array will become the
|
6191
6460
|
list of records in the record array that kicked off the request.
|
6192
6461
|
|
6462
|
+
If your primary array contains secondary (embedded) records of the same type,
|
6463
|
+
you cannot place these into the primary array `posts`. Instead, place the
|
6464
|
+
secondary items into an underscore prefixed property `_posts`, which will
|
6465
|
+
push these items into the store and will not affect the resulting query.
|
6466
|
+
|
6467
|
+
@method extractArray
|
6193
6468
|
@param {DS.Store} store
|
6194
6469
|
@param {subclass of DS.Model} type
|
6195
6470
|
@param {Object} payload
|
@@ -6198,17 +6473,28 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
6198
6473
|
to the original query.
|
6199
6474
|
*/
|
6200
6475
|
extractArray: function(store, primaryType, payload) {
|
6476
|
+
payload = this.normalizePayload(primaryType, payload);
|
6477
|
+
|
6201
6478
|
var primaryTypeName = primaryType.typeKey,
|
6202
6479
|
primaryArray;
|
6203
6480
|
|
6204
6481
|
for (var prop in payload) {
|
6205
|
-
var
|
6482
|
+
var typeKey = prop,
|
6483
|
+
forcedSecondary = false;
|
6484
|
+
|
6485
|
+
if (prop.charAt(0) === '_') {
|
6486
|
+
forcedSecondary = true;
|
6487
|
+
typeKey = prop.substr(1);
|
6488
|
+
}
|
6489
|
+
|
6490
|
+
var typeName = this.typeForRoot(typeKey),
|
6206
6491
|
type = store.modelFor(typeName),
|
6207
|
-
|
6492
|
+
typeSerializer = store.serializerFor(type),
|
6493
|
+
isPrimary = (!forcedSecondary && (typeName === primaryTypeName));
|
6208
6494
|
|
6209
6495
|
/*jshint loopfunc:true*/
|
6210
|
-
var normalizedArray = payload[prop]
|
6211
|
-
return
|
6496
|
+
var normalizedArray = map.call(payload[prop], function(hash) {
|
6497
|
+
return typeSerializer.normalize(type, hash, prop);
|
6212
6498
|
}, this);
|
6213
6499
|
|
6214
6500
|
if (isPrimary) {
|
@@ -6222,28 +6508,81 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
6222
6508
|
},
|
6223
6509
|
|
6224
6510
|
/**
|
6225
|
-
|
6226
|
-
|
6227
|
-
@param {String} key
|
6228
|
-
*/
|
6229
|
-
pluralize: function(key) {
|
6230
|
-
return Ember.String.pluralize(key);
|
6231
|
-
},
|
6511
|
+
This method allows you to push a payload containing top-level
|
6512
|
+
collections of records organized per type.
|
6232
6513
|
|
6233
|
-
|
6234
|
-
|
6235
|
-
|
6236
|
-
|
6237
|
-
|
6238
|
-
|
6239
|
-
|
6240
|
-
|
6514
|
+
```js
|
6515
|
+
{
|
6516
|
+
"posts": [{
|
6517
|
+
"id": "1",
|
6518
|
+
"title": "Rails is omakase",
|
6519
|
+
"author", "1",
|
6520
|
+
"comments": [ "1" ]
|
6521
|
+
}],
|
6522
|
+
"comments": [{
|
6523
|
+
"id": "1",
|
6524
|
+
"body": "FIRST
|
6525
|
+
}],
|
6526
|
+
"users": [{
|
6527
|
+
"id": "1",
|
6528
|
+
"name": "@d2h"
|
6529
|
+
}]
|
6530
|
+
}
|
6531
|
+
```
|
6241
6532
|
|
6242
|
-
|
6533
|
+
It will first normalize the payload, so you can use this to push
|
6534
|
+
in data streaming in from your server structured the same way
|
6535
|
+
that fetches and saves are structured.
|
6243
6536
|
|
6244
|
-
|
6245
|
-
|
6246
|
-
|
6537
|
+
@method pushPayload
|
6538
|
+
@param {DS.Store} store
|
6539
|
+
@param {Object} payload
|
6540
|
+
*/
|
6541
|
+
pushPayload: function(store, payload) {
|
6542
|
+
payload = this.normalizePayload(null, payload);
|
6543
|
+
|
6544
|
+
for (var prop in payload) {
|
6545
|
+
var typeName = this.typeForRoot(prop),
|
6546
|
+
type = store.modelFor(typeName);
|
6547
|
+
|
6548
|
+
/*jshint loopfunc:true*/
|
6549
|
+
var normalizedArray = map.call(payload[prop], function(hash) {
|
6550
|
+
return this.normalize(type, hash, prop);
|
6551
|
+
}, this);
|
6552
|
+
|
6553
|
+
store.pushMany(typeName, normalizedArray);
|
6554
|
+
}
|
6555
|
+
},
|
6556
|
+
|
6557
|
+
/**
|
6558
|
+
You can use this method to normalize the JSON root keys returned
|
6559
|
+
into the model type expected by your store.
|
6560
|
+
|
6561
|
+
For example, your server may return underscored root keys rather than
|
6562
|
+
the expected camelcased versions.
|
6563
|
+
|
6564
|
+
```js
|
6565
|
+
App.ApplicationSerializer = DS.RESTSerializer.extend({
|
6566
|
+
typeForRoot: function(root) {
|
6567
|
+
var camelized = Ember.String.camelize(root);
|
6568
|
+
return Ember.String.singularize(camelized);
|
6569
|
+
}
|
6570
|
+
});
|
6571
|
+
```
|
6572
|
+
|
6573
|
+
@method typeForRoot
|
6574
|
+
@param {String} root
|
6575
|
+
@returns String the model's typeKey
|
6576
|
+
*/
|
6577
|
+
typeForRoot: function(root) {
|
6578
|
+
return Ember.String.singularize(root);
|
6579
|
+
},
|
6580
|
+
|
6581
|
+
// SERIALIZE
|
6582
|
+
|
6583
|
+
/**
|
6584
|
+
Called when a record is saved in order to convert the
|
6585
|
+
record into JSON.
|
6247
6586
|
|
6248
6587
|
By default, it creates a JSON object with a key for
|
6249
6588
|
each attribute and belongsTo relationship.
|
@@ -6378,9 +6717,54 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
|
|
6378
6717
|
}
|
6379
6718
|
});
|
6380
6719
|
```
|
6720
|
+
|
6721
|
+
@method serialize
|
6722
|
+
@param record
|
6723
|
+
@param options
|
6381
6724
|
*/
|
6382
6725
|
serialize: function(record, options) {
|
6383
6726
|
return this._super.apply(this, arguments);
|
6727
|
+
},
|
6728
|
+
|
6729
|
+
/**
|
6730
|
+
You can use this method to customize the root keys serialized into the JSON.
|
6731
|
+
By default the REST Serializer sends camelized root keys.
|
6732
|
+
For example, your server may expect underscored root objects.
|
6733
|
+
|
6734
|
+
```js
|
6735
|
+
App.ApplicationSerializer = DS.RESTSerializer.extend({
|
6736
|
+
serializeIntoHash: function(data, type, record, options) {
|
6737
|
+
var root = Ember.String.decamelize(type.typeKey);
|
6738
|
+
data[root] = this.serialize(record, options);
|
6739
|
+
}
|
6740
|
+
});
|
6741
|
+
```
|
6742
|
+
|
6743
|
+
@method serializeIntoHash
|
6744
|
+
@param {Object} hash
|
6745
|
+
@param {subclass of DS.Model} type
|
6746
|
+
@param {DS.Model} record
|
6747
|
+
@param {Object} options
|
6748
|
+
*/
|
6749
|
+
serializeIntoHash: function(hash, type, record, options) {
|
6750
|
+
hash[type.typeKey] = this.serialize(record, options);
|
6751
|
+
},
|
6752
|
+
|
6753
|
+
/**
|
6754
|
+
You can use this method to customize how polymorphic objects are serialized.
|
6755
|
+
By default the JSON Serializer creates the key by appending `Type` to
|
6756
|
+
the attribute and value from the model's camelcased model name.
|
6757
|
+
|
6758
|
+
@method serializePolymorphicType
|
6759
|
+
@param {DS.Model} record
|
6760
|
+
@param {Object} json
|
6761
|
+
@param relationship
|
6762
|
+
*/
|
6763
|
+
serializePolymorphicType: function(record, json, relationship) {
|
6764
|
+
var key = relationship.key,
|
6765
|
+
belongsTo = get(record, key);
|
6766
|
+
key = this.keyForAttribute ? this.keyForAttribute(key) : key;
|
6767
|
+
json[key + "Type"] = belongsTo.constructor.typeKey;
|
6384
6768
|
}
|
6385
6769
|
});
|
6386
6770
|
|
@@ -6426,7 +6810,7 @@ var forEach = Ember.ArrayPolyfills.forEach;
|
|
6426
6810
|
|
6427
6811
|
### Conventional Names
|
6428
6812
|
|
6429
|
-
Attribute names in your JSON payload should be the
|
6813
|
+
Attribute names in your JSON payload should be the camelcased versions of
|
6430
6814
|
the attributes in your Ember.js models.
|
6431
6815
|
|
6432
6816
|
For example, if you have a `Person` model:
|
@@ -6444,8 +6828,8 @@ var forEach = Ember.ArrayPolyfills.forEach;
|
|
6444
6828
|
```js
|
6445
6829
|
{
|
6446
6830
|
"person": {
|
6447
|
-
"
|
6448
|
-
"
|
6831
|
+
"firstName": "Barack",
|
6832
|
+
"lastName": "Obama",
|
6449
6833
|
"occupation": "President"
|
6450
6834
|
}
|
6451
6835
|
}
|
@@ -6623,6 +7007,8 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6623
7007
|
This method will be called with the parent record and `/posts/1/comments`.
|
6624
7008
|
|
6625
7009
|
It will make an Ajax request to the originally specified URL.
|
7010
|
+
If the URL is host-relative (starting with a single slash), the
|
7011
|
+
request will use the host specified on the adapter (if any).
|
6626
7012
|
|
6627
7013
|
@method findHasMany
|
6628
7014
|
@see RESTAdapter/buildURL
|
@@ -6633,7 +7019,51 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6633
7019
|
@returns Promise
|
6634
7020
|
*/
|
6635
7021
|
findHasMany: function(store, record, url) {
|
6636
|
-
|
7022
|
+
var host = get(this, 'host'),
|
7023
|
+
id = get(record, 'id'),
|
7024
|
+
type = record.constructor.typeKey;
|
7025
|
+
|
7026
|
+
if (host && url.charAt(0) === '/' && url.charAt(1) !== '/') {
|
7027
|
+
url = host + url;
|
7028
|
+
}
|
7029
|
+
|
7030
|
+
return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
|
7031
|
+
},
|
7032
|
+
|
7033
|
+
/**
|
7034
|
+
Called by the store in order to fetch a JSON array for
|
7035
|
+
the unloaded records in a belongs-to relationship that were originally
|
7036
|
+
specified as a URL (inside of `links`).
|
7037
|
+
|
7038
|
+
For example, if your original payload looks like this:
|
7039
|
+
|
7040
|
+
```js
|
7041
|
+
{
|
7042
|
+
"person": {
|
7043
|
+
"id": 1,
|
7044
|
+
"name": "Tom Dale",
|
7045
|
+
"links": { "group": "/people/1/group" }
|
7046
|
+
}
|
7047
|
+
}
|
7048
|
+
```
|
7049
|
+
|
7050
|
+
This method will be called with the parent record and `/people/1/group`.
|
7051
|
+
|
7052
|
+
It will make an Ajax request to the originally specified URL.
|
7053
|
+
|
7054
|
+
@method findBelongsTo
|
7055
|
+
@see RESTAdapter/buildURL
|
7056
|
+
@see RESTAdapter/ajax
|
7057
|
+
@param {DS.Store} store
|
7058
|
+
@param {DS.Model} record
|
7059
|
+
@param {String} url
|
7060
|
+
@returns Promise
|
7061
|
+
*/
|
7062
|
+
findBelongsTo: function(store, record, url) {
|
7063
|
+
var id = get(record, 'id'),
|
7064
|
+
type = record.constructor.typeKey;
|
7065
|
+
|
7066
|
+
return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
|
6637
7067
|
},
|
6638
7068
|
|
6639
7069
|
/**
|
@@ -6656,7 +7086,9 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6656
7086
|
*/
|
6657
7087
|
createRecord: function(store, type, record) {
|
6658
7088
|
var data = {};
|
6659
|
-
|
7089
|
+
var serializer = store.serializerFor(type.typeKey);
|
7090
|
+
|
7091
|
+
serializer.serializeIntoHash(data, type, record, { includeId: true });
|
6660
7092
|
|
6661
7093
|
return this.ajax(this.buildURL(type.typeKey), "POST", { data: data });
|
6662
7094
|
},
|
@@ -6680,7 +7112,9 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6680
7112
|
*/
|
6681
7113
|
updateRecord: function(store, type, record) {
|
6682
7114
|
var data = {};
|
6683
|
-
|
7115
|
+
var serializer = store.serializerFor(type.typeKey);
|
7116
|
+
|
7117
|
+
serializer.serializeIntoHash(data, type, record);
|
6684
7118
|
|
6685
7119
|
var id = get(record, 'id');
|
6686
7120
|
|
@@ -6710,7 +7144,10 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6710
7144
|
/**
|
6711
7145
|
Builds a URL for a given type and optional ID.
|
6712
7146
|
|
6713
|
-
|
7147
|
+
By default, it pluralizes the type's name (for example,
|
7148
|
+
'post' becomes 'posts' and 'person' becomes 'people').
|
7149
|
+
|
7150
|
+
If an ID is specified, it adds the ID to the path generated
|
6714
7151
|
for the type, separated by a `/`.
|
6715
7152
|
|
6716
7153
|
@method buildURL
|
@@ -6719,50 +7156,95 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6719
7156
|
@returns String
|
6720
7157
|
*/
|
6721
7158
|
buildURL: function(type, id) {
|
6722
|
-
var
|
6723
|
-
|
6724
|
-
|
6725
|
-
|
6726
|
-
if (host) { url.push(host); }
|
6727
|
-
if (namespace) { url.push(namespace); }
|
7159
|
+
var url = [],
|
7160
|
+
host = get(this, 'host'),
|
7161
|
+
prefix = this.urlPrefix();
|
6728
7162
|
|
6729
|
-
url.push(this.
|
7163
|
+
if (type) { url.push(this.pathForType(type)); }
|
6730
7164
|
if (id) { url.push(id); }
|
6731
7165
|
|
7166
|
+
if (prefix) { url.unshift(prefix); }
|
7167
|
+
|
6732
7168
|
url = url.join('/');
|
6733
|
-
if (!host) { url = '/' + url; }
|
7169
|
+
if (!host && url) { url = '/' + url; }
|
6734
7170
|
|
6735
7171
|
return url;
|
6736
7172
|
},
|
6737
7173
|
|
7174
|
+
urlPrefix: function(path, parentURL) {
|
7175
|
+
var host = get(this, 'host'),
|
7176
|
+
namespace = get(this, 'namespace'),
|
7177
|
+
url = [];
|
7178
|
+
|
7179
|
+
if (path) {
|
7180
|
+
// Absolute path
|
7181
|
+
if (path.charAt(0) === '/') {
|
7182
|
+
if (host) {
|
7183
|
+
path = path.slice(1);
|
7184
|
+
url.push(host);
|
7185
|
+
}
|
7186
|
+
// Relative path
|
7187
|
+
} else if (!/^http(s)?:\/\//.test(path)) {
|
7188
|
+
url.push(parentURL);
|
7189
|
+
}
|
7190
|
+
} else {
|
7191
|
+
if (host) { url.push(host); }
|
7192
|
+
if (namespace) { url.push(namespace); }
|
7193
|
+
}
|
7194
|
+
|
7195
|
+
if (path) {
|
7196
|
+
url.push(path);
|
7197
|
+
}
|
7198
|
+
|
7199
|
+
return url.join('/');
|
7200
|
+
},
|
7201
|
+
|
6738
7202
|
/**
|
6739
|
-
Determines the pathname
|
7203
|
+
Determines the pathname for a given type.
|
6740
7204
|
|
6741
7205
|
By default, it pluralizes the type's name (for example,
|
6742
7206
|
'post' becomes 'posts' and 'person' becomes 'people').
|
6743
7207
|
|
6744
|
-
### Pathname
|
7208
|
+
### Pathname customization
|
6745
7209
|
|
6746
7210
|
For example if you have an object LineItem with an
|
6747
7211
|
endpoint of "/line_items/".
|
6748
7212
|
|
6749
7213
|
```js
|
6750
7214
|
DS.RESTAdapter.reopen({
|
6751
|
-
|
7215
|
+
pathForType: function(type) {
|
6752
7216
|
var decamelized = Ember.String.decamelize(type);
|
6753
7217
|
return Ember.String.pluralize(decamelized);
|
6754
7218
|
};
|
6755
7219
|
});
|
6756
7220
|
```
|
6757
7221
|
|
6758
|
-
@method
|
7222
|
+
@method pathForType
|
6759
7223
|
@param {String} type
|
6760
7224
|
@returns String
|
6761
7225
|
**/
|
6762
|
-
|
7226
|
+
pathForType: function(type) {
|
6763
7227
|
return Ember.String.pluralize(type);
|
6764
7228
|
},
|
6765
7229
|
|
7230
|
+
/**
|
7231
|
+
Takes an ajax response, and returns a relavant error.
|
7232
|
+
|
7233
|
+
By default, it has the following behavior:
|
7234
|
+
|
7235
|
+
* It simply returns the ajax response.
|
7236
|
+
|
7237
|
+
@method ajaxError
|
7238
|
+
@param jqXHR
|
7239
|
+
*/
|
7240
|
+
ajaxError: function(jqXHR) {
|
7241
|
+
if (jqXHR) {
|
7242
|
+
jqXHR.then = null;
|
7243
|
+
}
|
7244
|
+
|
7245
|
+
return jqXHR;
|
7246
|
+
},
|
7247
|
+
|
6766
7248
|
/**
|
6767
7249
|
Takes a URL, an HTTP method and a hash of data, and makes an
|
6768
7250
|
HTTP request.
|
@@ -6790,40 +7272,43 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6790
7272
|
var adapter = this;
|
6791
7273
|
|
6792
7274
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
6793
|
-
hash =
|
6794
|
-
hash.url = url;
|
6795
|
-
hash.type = type;
|
6796
|
-
hash.dataType = 'json';
|
6797
|
-
hash.context = adapter;
|
6798
|
-
|
6799
|
-
if (hash.data && type !== 'GET') {
|
6800
|
-
hash.contentType = 'application/json; charset=utf-8';
|
6801
|
-
hash.data = JSON.stringify(hash.data);
|
6802
|
-
}
|
6803
|
-
|
6804
|
-
if (adapter.headers !== undefined) {
|
6805
|
-
var headers = adapter.headers;
|
6806
|
-
hash.beforeSend = function (xhr) {
|
6807
|
-
forEach.call(Ember.keys(headers), function(key) {
|
6808
|
-
xhr.setRequestHeader(key, headers[key]);
|
6809
|
-
});
|
6810
|
-
};
|
6811
|
-
}
|
7275
|
+
hash = adapter.ajaxOptions(url, type, hash);
|
6812
7276
|
|
6813
7277
|
hash.success = function(json) {
|
6814
7278
|
Ember.run(null, resolve, json);
|
6815
7279
|
};
|
6816
7280
|
|
6817
7281
|
hash.error = function(jqXHR, textStatus, errorThrown) {
|
6818
|
-
|
6819
|
-
jqXHR.then = null;
|
6820
|
-
}
|
6821
|
-
|
6822
|
-
Ember.run(null, reject, jqXHR);
|
7282
|
+
Ember.run(null, reject, adapter.ajaxError(jqXHR));
|
6823
7283
|
};
|
6824
7284
|
|
6825
7285
|
Ember.$.ajax(hash);
|
6826
7286
|
});
|
7287
|
+
},
|
7288
|
+
|
7289
|
+
ajaxOptions: function(url, type, hash) {
|
7290
|
+
hash = hash || {};
|
7291
|
+
hash.url = url;
|
7292
|
+
hash.type = type;
|
7293
|
+
hash.dataType = 'json';
|
7294
|
+
hash.context = this;
|
7295
|
+
|
7296
|
+
if (hash.data && type !== 'GET') {
|
7297
|
+
hash.contentType = 'application/json; charset=utf-8';
|
7298
|
+
hash.data = JSON.stringify(hash.data);
|
7299
|
+
}
|
7300
|
+
|
7301
|
+
if (this.headers !== undefined) {
|
7302
|
+
var headers = this.headers;
|
7303
|
+
hash.beforeSend = function (xhr) {
|
7304
|
+
forEach.call(Ember.keys(headers), function(key) {
|
7305
|
+
xhr.setRequestHeader(key, headers[key]);
|
7306
|
+
});
|
7307
|
+
};
|
7308
|
+
}
|
7309
|
+
|
7310
|
+
|
7311
|
+
return hash;
|
6827
7312
|
}
|
6828
7313
|
|
6829
7314
|
});
|
@@ -6845,16 +7330,20 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|
6845
7330
|
DS.Model.reopen({
|
6846
7331
|
|
6847
7332
|
/**
|
6848
|
-
|
6849
|
-
|
7333
|
+
Provides info about the model for debugging purposes
|
7334
|
+
by grouping the properties into more semantic groups.
|
7335
|
+
|
7336
|
+
Meant to be used by debugging tools such as the Chrome Ember Extension.
|
6850
7337
|
|
6851
|
-
|
7338
|
+
- Groups all attributes in "Attributes" group.
|
7339
|
+
- Groups all belongsTo relationships in "Belongs To" group.
|
7340
|
+
- Groups all hasMany relationships in "Has Many" group.
|
7341
|
+
- Groups all flags in "Flags" group.
|
7342
|
+
- Flags relationship CPs as expensive properties.
|
6852
7343
|
|
6853
|
-
|
6854
|
-
|
6855
|
-
|
6856
|
-
- Groups all flags in "Flags" group.
|
6857
|
-
- Flags relationship CPs as expensive properties.
|
7344
|
+
@method _debugInfo
|
7345
|
+
@for DS.Model
|
7346
|
+
@private
|
6858
7347
|
*/
|
6859
7348
|
_debugInfo: function() {
|
6860
7349
|
var attributes = ['id'],
|
@@ -6874,7 +7363,7 @@ DS.Model.reopen({
|
|
6874
7363
|
{
|
6875
7364
|
name: 'Attributes',
|
6876
7365
|
properties: attributes,
|
6877
|
-
expand: true
|
7366
|
+
expand: true
|
6878
7367
|
},
|
6879
7368
|
{
|
6880
7369
|
name: 'Belongs To',
|
@@ -6919,26 +7408,6 @@ DS.Model.reopen({
|
|
6919
7408
|
|
6920
7409
|
|
6921
7410
|
(function() {
|
6922
|
-
//Copyright (C) 2011 by Living Social, Inc.
|
6923
|
-
|
6924
|
-
//Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6925
|
-
//this software and associated documentation files (the "Software"), to deal in
|
6926
|
-
//the Software without restriction, including without limitation the rights to
|
6927
|
-
//use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
6928
|
-
//of the Software, and to permit persons to whom the Software is furnished to do
|
6929
|
-
//so, subject to the following conditions:
|
6930
|
-
|
6931
|
-
//The above copyright notice and this permission notice shall be included in all
|
6932
|
-
//copies or substantial portions of the Software.
|
6933
|
-
|
6934
|
-
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
6935
|
-
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
6936
|
-
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
6937
|
-
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
6938
|
-
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
6939
|
-
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
6940
|
-
//SOFTWARE.
|
6941
|
-
|
6942
7411
|
/**
|
6943
7412
|
Ember Data
|
6944
7413
|
|
@@ -6981,6 +7450,64 @@ function loadIrregular(rules, irregularPairs) {
|
|
6981
7450
|
}
|
6982
7451
|
}
|
6983
7452
|
|
7453
|
+
/**
|
7454
|
+
Inflector.Ember provides a mechanism for supplying inflection rules for your
|
7455
|
+
application. Ember includes a default set of inflection rules, and provides an
|
7456
|
+
API for providing additional rules.
|
7457
|
+
|
7458
|
+
Examples:
|
7459
|
+
|
7460
|
+
Creating an inflector with no rules.
|
7461
|
+
|
7462
|
+
```js
|
7463
|
+
var inflector = new Ember.Inflector();
|
7464
|
+
```
|
7465
|
+
|
7466
|
+
Creating an inflector with the default ember ruleset.
|
7467
|
+
|
7468
|
+
```js
|
7469
|
+
var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
|
7470
|
+
|
7471
|
+
inflector.pluralize('cow') //=> 'kine'
|
7472
|
+
inflector.singularize('kine') //=> 'cow'
|
7473
|
+
```
|
7474
|
+
|
7475
|
+
Creating an inflector and adding rules later.
|
7476
|
+
|
7477
|
+
```javascript
|
7478
|
+
var inflector = Ember.Inflector.inflector;
|
7479
|
+
|
7480
|
+
inflector.pluralize('advice') // => 'advices'
|
7481
|
+
inflector.uncountable('advice');
|
7482
|
+
inflector.pluralize('advice') // => 'advice'
|
7483
|
+
|
7484
|
+
inflector.pluralize('formula') // => 'formulas'
|
7485
|
+
inflector.irregular('formula', 'formulae');
|
7486
|
+
inflector.pluralize('formula') // => 'formulae'
|
7487
|
+
|
7488
|
+
// you would not need to add these as they are the default rules
|
7489
|
+
inflector.plural(/$/, 's');
|
7490
|
+
inflector.singular(/s$/i, '');
|
7491
|
+
```
|
7492
|
+
|
7493
|
+
Creating an inflector with a nondefault ruleset.
|
7494
|
+
|
7495
|
+
```javascript
|
7496
|
+
var rules = {
|
7497
|
+
plurals: [ /$/, 's' ],
|
7498
|
+
singular: [ /\s$/, '' ],
|
7499
|
+
irregularPairs: [
|
7500
|
+
[ 'cow', 'kine' ]
|
7501
|
+
],
|
7502
|
+
uncountable: [ 'fish' ]
|
7503
|
+
};
|
7504
|
+
|
7505
|
+
var inflector = new Ember.Inflector(rules);
|
7506
|
+
```
|
7507
|
+
|
7508
|
+
@class Inflector
|
7509
|
+
@namespace Ember
|
7510
|
+
*/
|
6984
7511
|
function Inflector(ruleSet) {
|
6985
7512
|
ruleSet = ruleSet || {};
|
6986
7513
|
ruleSet.uncountable = ruleSet.uncountable || {};
|
@@ -6999,15 +7526,66 @@ function Inflector(ruleSet) {
|
|
6999
7526
|
}
|
7000
7527
|
|
7001
7528
|
Inflector.prototype = {
|
7529
|
+
/**
|
7530
|
+
@method plural
|
7531
|
+
@param {RegExp} regex
|
7532
|
+
@param {String} string
|
7533
|
+
*/
|
7534
|
+
plural: function(regex, string) {
|
7535
|
+
this.rules.plurals.push([regex, string]);
|
7536
|
+
},
|
7537
|
+
|
7538
|
+
/**
|
7539
|
+
@method singular
|
7540
|
+
@param {RegExp} regex
|
7541
|
+
@param {String} string
|
7542
|
+
*/
|
7543
|
+
singular: function(regex, string) {
|
7544
|
+
this.rules.singular.push([regex, string]);
|
7545
|
+
},
|
7546
|
+
|
7547
|
+
/**
|
7548
|
+
@method uncountable
|
7549
|
+
@param {String} regex
|
7550
|
+
*/
|
7551
|
+
uncountable: function(string) {
|
7552
|
+
loadUncountable(this.rules, [string]);
|
7553
|
+
},
|
7554
|
+
|
7555
|
+
/**
|
7556
|
+
@method irregular
|
7557
|
+
@param {String} singular
|
7558
|
+
@param {String} plural
|
7559
|
+
*/
|
7560
|
+
irregular: function (singular, plural) {
|
7561
|
+
loadIrregular(this.rules, [[singular, plural]]);
|
7562
|
+
},
|
7563
|
+
|
7564
|
+
/**
|
7565
|
+
@method pluralize
|
7566
|
+
@param {String} word
|
7567
|
+
*/
|
7002
7568
|
pluralize: function(word) {
|
7003
|
-
return this.inflect(word, this.rules.plurals);
|
7569
|
+
return this.inflect(word, this.rules.plurals, this.rules.irregular);
|
7004
7570
|
},
|
7005
7571
|
|
7572
|
+
/**
|
7573
|
+
@method singularize
|
7574
|
+
@param {String} word
|
7575
|
+
*/
|
7006
7576
|
singularize: function(word) {
|
7007
|
-
return this.inflect(word, this.rules.singular);
|
7577
|
+
return this.inflect(word, this.rules.singular, this.rules.irregularInverse);
|
7008
7578
|
},
|
7009
7579
|
|
7010
|
-
|
7580
|
+
/**
|
7581
|
+
@protected
|
7582
|
+
|
7583
|
+
@method inflect
|
7584
|
+
@param {String} word
|
7585
|
+
@param {Object} typeRules
|
7586
|
+
@param {Object} irregular
|
7587
|
+
*/
|
7588
|
+
inflect: function(word, typeRules, irregular) {
|
7011
7589
|
var inflection, substitution, result, lowercase, isBlank,
|
7012
7590
|
isUncountable, isIrregular, isIrregularInverse, rule;
|
7013
7591
|
|
@@ -7025,18 +7603,12 @@ Inflector.prototype = {
|
|
7025
7603
|
return word;
|
7026
7604
|
}
|
7027
7605
|
|
7028
|
-
isIrregular =
|
7606
|
+
isIrregular = irregular && irregular[lowercase];
|
7029
7607
|
|
7030
7608
|
if (isIrregular) {
|
7031
7609
|
return isIrregular;
|
7032
7610
|
}
|
7033
7611
|
|
7034
|
-
isIrregularInverse = this.rules.irregularInverse[lowercase];
|
7035
|
-
|
7036
|
-
if (isIrregularInverse) {
|
7037
|
-
return isIrregularInverse;
|
7038
|
-
}
|
7039
|
-
|
7040
7612
|
for (var i = typeRules.length, min = 0; i > min; i--) {
|
7041
7613
|
inflection = typeRules[i-1];
|
7042
7614
|
rule = inflection[0];
|
@@ -7148,7 +7720,7 @@ Ember.Inflector.defaultRules = {
|
|
7148
7720
|
|
7149
7721
|
|
7150
7722
|
(function() {
|
7151
|
-
if (Ember.EXTEND_PROTOTYPES) {
|
7723
|
+
if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
7152
7724
|
/**
|
7153
7725
|
See {{#crossLink "Ember.String/pluralize"}}{{/crossLink}}
|
7154
7726
|
|
@@ -7181,6 +7753,363 @@ Ember.Inflector.inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
|
|
7181
7753
|
|
7182
7754
|
|
7183
7755
|
|
7756
|
+
(function() {
|
7757
|
+
|
7758
|
+
})();
|
7759
|
+
|
7760
|
+
(function() {
|
7761
|
+
/**
|
7762
|
+
@module ember-data
|
7763
|
+
*/
|
7764
|
+
|
7765
|
+
var get = Ember.get;
|
7766
|
+
var forEach = Ember.EnumerableUtils.forEach;
|
7767
|
+
|
7768
|
+
DS.ActiveModelSerializer = DS.RESTSerializer.extend({
|
7769
|
+
// SERIALIZE
|
7770
|
+
|
7771
|
+
/**
|
7772
|
+
Converts camelcased attributes to underscored when serializing.
|
7773
|
+
|
7774
|
+
@method keyForAttribute
|
7775
|
+
@param {String} attribute
|
7776
|
+
@returns String
|
7777
|
+
*/
|
7778
|
+
keyForAttribute: function(attr) {
|
7779
|
+
return Ember.String.decamelize(attr);
|
7780
|
+
},
|
7781
|
+
|
7782
|
+
/**
|
7783
|
+
Underscores relationship names and appends "_id" or "_ids" when serializing
|
7784
|
+
relationship keys.
|
7785
|
+
|
7786
|
+
@method keyForRelationship
|
7787
|
+
@param {String} key
|
7788
|
+
@param {String} kind
|
7789
|
+
@returns String
|
7790
|
+
*/
|
7791
|
+
keyForRelationship: function(key, kind) {
|
7792
|
+
key = Ember.String.decamelize(key);
|
7793
|
+
if (kind === "belongsTo") {
|
7794
|
+
return key + "_id";
|
7795
|
+
} else if (kind === "hasMany") {
|
7796
|
+
return Ember.String.singularize(key) + "_ids";
|
7797
|
+
} else {
|
7798
|
+
return key;
|
7799
|
+
}
|
7800
|
+
},
|
7801
|
+
|
7802
|
+
/**
|
7803
|
+
Serialize has-may relationship when it is configured as embedded objects.
|
7804
|
+
|
7805
|
+
@method serializeHasMany
|
7806
|
+
*/
|
7807
|
+
serializeHasMany: function(record, json, relationship) {
|
7808
|
+
var key = relationship.key,
|
7809
|
+
attrs = get(this, 'attrs'),
|
7810
|
+
embed = attrs && attrs[key] && attrs[key].embedded === 'always';
|
7811
|
+
|
7812
|
+
if (embed) {
|
7813
|
+
json[this.keyForAttribute(key)] = get(record, key).map(function(relation) {
|
7814
|
+
var data = relation.serialize(),
|
7815
|
+
primaryKey = get(this, 'primaryKey');
|
7816
|
+
|
7817
|
+
data[primaryKey] = get(relation, primaryKey);
|
7818
|
+
|
7819
|
+
return data;
|
7820
|
+
}, this);
|
7821
|
+
}
|
7822
|
+
},
|
7823
|
+
|
7824
|
+
/**
|
7825
|
+
Underscores the JSON root keys when serializing.
|
7826
|
+
|
7827
|
+
@method serializeIntoHash
|
7828
|
+
@param {Object} hash
|
7829
|
+
@param {subclass of DS.Model} type
|
7830
|
+
@param {DS.Model} record
|
7831
|
+
@param {Object} options
|
7832
|
+
*/
|
7833
|
+
serializeIntoHash: function(data, type, record, options) {
|
7834
|
+
var root = Ember.String.decamelize(type.typeKey);
|
7835
|
+
data[root] = this.serialize(record, options);
|
7836
|
+
},
|
7837
|
+
|
7838
|
+
/**
|
7839
|
+
Serializes a polymorphic type as a fully capitalized model name.
|
7840
|
+
|
7841
|
+
@method serializePolymorphicType
|
7842
|
+
@param {DS.Model} record
|
7843
|
+
@param {Object} json
|
7844
|
+
@param relationship
|
7845
|
+
*/
|
7846
|
+
serializePolymorphicType: function(record, json, relationship) {
|
7847
|
+
var key = relationship.key,
|
7848
|
+
belongsTo = get(record, key);
|
7849
|
+
key = this.keyForAttribute(key);
|
7850
|
+
json[key + "_type"] = Ember.String.capitalize(belongsTo.constructor.typeKey);
|
7851
|
+
},
|
7852
|
+
|
7853
|
+
// EXTRACT
|
7854
|
+
|
7855
|
+
/**
|
7856
|
+
Extracts the model typeKey from underscored root objects.
|
7857
|
+
|
7858
|
+
@method typeForRoot
|
7859
|
+
@param {String} root
|
7860
|
+
@returns String the model's typeKey
|
7861
|
+
*/
|
7862
|
+
typeForRoot: function(root) {
|
7863
|
+
var camelized = Ember.String.camelize(root);
|
7864
|
+
return Ember.String.singularize(camelized);
|
7865
|
+
},
|
7866
|
+
|
7867
|
+
/**
|
7868
|
+
Normalize the polymorphic type from the JSON.
|
7869
|
+
|
7870
|
+
Normalize:
|
7871
|
+
```js
|
7872
|
+
{
|
7873
|
+
id: "1"
|
7874
|
+
minion: { type: "evil_minion", id: "12"}
|
7875
|
+
}
|
7876
|
+
```
|
7877
|
+
|
7878
|
+
To:
|
7879
|
+
```js
|
7880
|
+
{
|
7881
|
+
id: "1"
|
7882
|
+
minion: { type: "evilMinion", id: "12"}
|
7883
|
+
}
|
7884
|
+
```
|
7885
|
+
|
7886
|
+
@method normalizeRelationships
|
7887
|
+
@private
|
7888
|
+
*/
|
7889
|
+
normalizeRelationships: function(type, hash) {
|
7890
|
+
var payloadKey, payload;
|
7891
|
+
|
7892
|
+
if (this.keyForRelationship) {
|
7893
|
+
type.eachRelationship(function(key, relationship) {
|
7894
|
+
if (relationship.options.polymorphic) {
|
7895
|
+
payloadKey = this.keyForAttribute(key);
|
7896
|
+
payload = hash[payloadKey];
|
7897
|
+
if (payload && payload.type) {
|
7898
|
+
payload.type = this.typeForRoot(payload.type);
|
7899
|
+
} else if (payload && relationship.kind === "hasMany") {
|
7900
|
+
var self = this;
|
7901
|
+
forEach(payload, function(single) {
|
7902
|
+
single.type = self.typeForRoot(single.type);
|
7903
|
+
});
|
7904
|
+
}
|
7905
|
+
} else {
|
7906
|
+
payloadKey = this.keyForRelationship(key, relationship.kind);
|
7907
|
+
payload = hash[payloadKey];
|
7908
|
+
}
|
7909
|
+
|
7910
|
+
hash[key] = payload;
|
7911
|
+
|
7912
|
+
if (key !== payloadKey) {
|
7913
|
+
delete hash[payloadKey];
|
7914
|
+
}
|
7915
|
+
}, this);
|
7916
|
+
}
|
7917
|
+
},
|
7918
|
+
|
7919
|
+
extractSingle: function(store, primaryType, payload, recordId, requestType) {
|
7920
|
+
var root = this.keyForAttribute(primaryType.typeKey),
|
7921
|
+
partial = payload[root];
|
7922
|
+
|
7923
|
+
updatePayloadWithEmbedded(store, this, primaryType, partial, payload);
|
7924
|
+
|
7925
|
+
return this._super(store, primaryType, payload, recordId, requestType);
|
7926
|
+
},
|
7927
|
+
|
7928
|
+
extractArray: function(store, type, payload) {
|
7929
|
+
var root = this.keyForAttribute(type.typeKey),
|
7930
|
+
partials = payload[Ember.String.pluralize(root)];
|
7931
|
+
|
7932
|
+
forEach(partials, function(partial) {
|
7933
|
+
updatePayloadWithEmbedded(store, this, type, partial, payload);
|
7934
|
+
}, this);
|
7935
|
+
|
7936
|
+
return this._super(store, type, payload);
|
7937
|
+
}
|
7938
|
+
});
|
7939
|
+
|
7940
|
+
function updatePayloadWithEmbedded(store, serializer, type, partial, payload) {
|
7941
|
+
var attrs = get(serializer, 'attrs');
|
7942
|
+
|
7943
|
+
if (!attrs) {
|
7944
|
+
return;
|
7945
|
+
}
|
7946
|
+
|
7947
|
+
type.eachRelationship(function(key, relationship) {
|
7948
|
+
var expandedKey, embeddedTypeKey, attribute, ids,
|
7949
|
+
config = attrs[key],
|
7950
|
+
serializer = store.serializerFor(relationship.type.typeKey),
|
7951
|
+
primaryKey = get(serializer, "primaryKey");
|
7952
|
+
|
7953
|
+
if (relationship.kind !== "hasMany") {
|
7954
|
+
return;
|
7955
|
+
}
|
7956
|
+
|
7957
|
+
if (config && (config.embedded === 'always' || config.embedded === 'load')) {
|
7958
|
+
// underscore forces the embedded records to be side loaded.
|
7959
|
+
// it is needed when main type === relationship.type
|
7960
|
+
embeddedTypeKey = '_' + Ember.String.pluralize(relationship.type.typeKey);
|
7961
|
+
expandedKey = this.keyForRelationship(key, relationship.kind);
|
7962
|
+
attribute = this.keyForAttribute(key);
|
7963
|
+
ids = [];
|
7964
|
+
|
7965
|
+
if (!partial[attribute]) {
|
7966
|
+
return;
|
7967
|
+
}
|
7968
|
+
|
7969
|
+
payload[embeddedTypeKey] = payload[embeddedTypeKey] || [];
|
7970
|
+
|
7971
|
+
forEach(partial[attribute], function(data) {
|
7972
|
+
var embeddedType = store.modelFor(relationship.type.typeKey);
|
7973
|
+
updatePayloadWithEmbedded(store, serializer, embeddedType, data, payload);
|
7974
|
+
ids.push(data[primaryKey]);
|
7975
|
+
payload[embeddedTypeKey].push(data);
|
7976
|
+
});
|
7977
|
+
|
7978
|
+
partial[expandedKey] = ids;
|
7979
|
+
delete partial[attribute];
|
7980
|
+
}
|
7981
|
+
}, serializer);
|
7982
|
+
}
|
7983
|
+
|
7984
|
+
})();
|
7985
|
+
|
7986
|
+
|
7987
|
+
|
7988
|
+
(function() {
|
7989
|
+
/**
|
7990
|
+
@module ember-data
|
7991
|
+
*/
|
7992
|
+
|
7993
|
+
var forEach = Ember.EnumerableUtils.forEach;
|
7994
|
+
|
7995
|
+
/**
|
7996
|
+
The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
|
7997
|
+
with a JSON API that uses an underscored naming convention instead of camelcasing.
|
7998
|
+
It has been designed to work out of the box with the
|
7999
|
+
[active_model_serializers](http://github.com/rails-api/active_model_serializers)
|
8000
|
+
Ruby gem.
|
8001
|
+
|
8002
|
+
## JSON Structure
|
8003
|
+
|
8004
|
+
The ActiveModelAdapter expects the JSON returned from your server to follow
|
8005
|
+
the REST adapter conventions substituting underscored keys for camelcased ones.
|
8006
|
+
|
8007
|
+
### Conventional Names
|
8008
|
+
|
8009
|
+
Attribute names in your JSON payload should be the underscored versions of
|
8010
|
+
the attributes in your Ember.js models.
|
8011
|
+
|
8012
|
+
For example, if you have a `Person` model:
|
8013
|
+
|
8014
|
+
```js
|
8015
|
+
App.FamousPerson = DS.Model.extend({
|
8016
|
+
firstName: DS.attr('string'),
|
8017
|
+
lastName: DS.attr('string'),
|
8018
|
+
occupation: DS.attr('string')
|
8019
|
+
});
|
8020
|
+
```
|
8021
|
+
|
8022
|
+
The JSON returned should look like this:
|
8023
|
+
|
8024
|
+
```js
|
8025
|
+
{
|
8026
|
+
"famous_person": {
|
8027
|
+
"first_name": "Barack",
|
8028
|
+
"last_name": "Obama",
|
8029
|
+
"occupation": "President"
|
8030
|
+
}
|
8031
|
+
}
|
8032
|
+
```
|
8033
|
+
|
8034
|
+
@class ActiveModelAdapter
|
8035
|
+
@constructor
|
8036
|
+
@namespace DS
|
8037
|
+
@extends DS.Adapter
|
8038
|
+
**/
|
8039
|
+
|
8040
|
+
DS.ActiveModelAdapter = DS.RESTAdapter.extend({
|
8041
|
+
defaultSerializer: '_ams',
|
8042
|
+
/**
|
8043
|
+
The ActiveModelAdapter overrides the `pathForType` method
|
8044
|
+
to build underscored URLs.
|
8045
|
+
|
8046
|
+
```js
|
8047
|
+
this.pathForType("famousPerson");
|
8048
|
+
//=> "famous_people"
|
8049
|
+
```
|
8050
|
+
|
8051
|
+
@method pathForType
|
8052
|
+
@param {String} type
|
8053
|
+
@returns String
|
8054
|
+
*/
|
8055
|
+
pathForType: function(type) {
|
8056
|
+
var decamelized = Ember.String.decamelize(type);
|
8057
|
+
return Ember.String.pluralize(decamelized);
|
8058
|
+
},
|
8059
|
+
|
8060
|
+
/**
|
8061
|
+
The ActiveModelAdapter overrides the `ajaxError` method
|
8062
|
+
to return a DS.InvalidError for all 422 Unprocessable Entity
|
8063
|
+
responses.
|
8064
|
+
|
8065
|
+
@method ajaxError
|
8066
|
+
@param jqXHR
|
8067
|
+
@returns error
|
8068
|
+
*/
|
8069
|
+
ajaxError: function(jqXHR) {
|
8070
|
+
var error = this._super(jqXHR);
|
8071
|
+
|
8072
|
+
if (jqXHR && jqXHR.status === 422) {
|
8073
|
+
var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)["errors"],
|
8074
|
+
errors = {};
|
8075
|
+
|
8076
|
+
forEach(Ember.keys(jsonErrors), function(key) {
|
8077
|
+
errors[Ember.String.camelize(key)] = jsonErrors[key];
|
8078
|
+
});
|
8079
|
+
|
8080
|
+
return new DS.InvalidError(errors);
|
8081
|
+
} else {
|
8082
|
+
return error;
|
8083
|
+
}
|
8084
|
+
}
|
8085
|
+
});
|
8086
|
+
|
8087
|
+
})();
|
8088
|
+
|
8089
|
+
|
8090
|
+
|
8091
|
+
(function() {
|
8092
|
+
|
8093
|
+
})();
|
8094
|
+
|
8095
|
+
|
8096
|
+
|
8097
|
+
(function() {
|
8098
|
+
Ember.onLoad('Ember.Application', function(Application) {
|
8099
|
+
Application.initializer({
|
8100
|
+
name: "activeModelAdapter",
|
8101
|
+
|
8102
|
+
initialize: function(container, application) {
|
8103
|
+
application.register('serializer:_ams', DS.ActiveModelSerializer);
|
8104
|
+
application.register('adapter:_ams', DS.ActiveModelAdapter);
|
8105
|
+
}
|
8106
|
+
});
|
8107
|
+
});
|
8108
|
+
|
8109
|
+
})();
|
8110
|
+
|
8111
|
+
|
8112
|
+
|
7184
8113
|
(function() {
|
7185
8114
|
|
7186
8115
|
})();
|