ember-data-source 1.0.0.beta.2 → 1.0.0.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
})();
|