2015-02-13 07:22:32 +03:00
|
|
|
import Ember from 'ember';
|
2014-12-26 03:01:02 +03:00
|
|
|
import BaseAdapter from 'ghost/adapters/base';
|
2014-07-21 01:48:24 +04:00
|
|
|
|
|
|
|
// EmbeddedRelationAdapter will augment the query object in calls made to
|
2015-09-03 14:06:50 +03:00
|
|
|
// DS.Store#findRecord, findAll, query, and queryRecord with the correct "includes"
|
2014-07-21 01:48:24 +04:00
|
|
|
// (?include=relatedType) by introspecting on the provided subclass of the DS.Model.
|
2014-12-26 03:01:02 +03:00
|
|
|
// In cases where there is no query object (DS.Model#save, or simple finds) the URL
|
|
|
|
// that is built will be augmented with ?include=... where appropriate.
|
2014-07-21 01:48:24 +04:00
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// If a model has an embedded hasMany relation, the related type will be included:
|
|
|
|
// roles: DS.hasMany('role', { embedded: 'always' }) => ?include=roles
|
|
|
|
|
2015-08-19 14:55:40 +03:00
|
|
|
export default BaseAdapter.extend({
|
2015-09-03 14:06:50 +03:00
|
|
|
find: function (store, type, id, snapshot) {
|
|
|
|
return this.ajax(this.buildIncludeURL(store, type.modelName, id, snapshot, 'find'), 'GET');
|
2014-07-21 01:48:24 +04:00
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
findRecord: function (store, type, id, snapshot) {
|
|
|
|
return this.ajax(this.buildIncludeURL(store, type.modelName, id, snapshot, 'findRecord'), 'GET');
|
2014-07-21 01:48:24 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
findAll: function (store, type, sinceToken) {
|
2015-09-03 14:06:50 +03:00
|
|
|
var query, url;
|
2014-12-26 03:01:02 +03:00
|
|
|
|
|
|
|
if (sinceToken) {
|
2015-09-03 14:06:50 +03:00
|
|
|
query = {since: sinceToken};
|
2014-12-26 03:01:02 +03:00
|
|
|
}
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
url = this.buildIncludeURL(store, type.modelName, null, null, 'findAll');
|
|
|
|
|
|
|
|
return this.ajax(url, 'GET', {data: query});
|
|
|
|
},
|
|
|
|
|
|
|
|
query: function (store, type, query) {
|
|
|
|
return this._super(store, type, this.buildQuery(store, type.modelName, query));
|
|
|
|
},
|
|
|
|
|
|
|
|
queryRecord: function (store, type, query) {
|
|
|
|
return this._super(store, type, this.buildQuery(store, type.modelName, query));
|
2014-07-21 01:48:24 +04:00
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
createRecord: function (store, type, snapshot) {
|
|
|
|
return this.saveRecord(store, type, snapshot, {method: 'POST'});
|
2014-12-26 03:01:02 +03:00
|
|
|
},
|
2014-07-21 01:48:24 +04:00
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
updateRecord: function (store, type, snapshot) {
|
2014-12-26 03:01:02 +03:00
|
|
|
var options = {
|
|
|
|
method: 'PUT',
|
2015-09-03 14:06:50 +03:00
|
|
|
id: Ember.get(snapshot, 'id')
|
2014-12-26 03:01:02 +03:00
|
|
|
};
|
2014-07-21 01:48:24 +04:00
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
return this.saveRecord(store, type, snapshot, options);
|
2014-12-26 03:01:02 +03:00
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
saveRecord: function (store, type, snapshot, options) {
|
2014-12-26 03:01:02 +03:00
|
|
|
options = options || {};
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
var url = this.buildIncludeURL(store, type.modelName, options.id, snapshot, 'createRecord'),
|
|
|
|
payload = this.preparePayload(store, type, snapshot);
|
2014-12-26 03:01:02 +03:00
|
|
|
|
|
|
|
return this.ajax(url, options.method, payload);
|
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
preparePayload: function (store, type, snapshot) {
|
2015-06-03 05:56:42 +03:00
|
|
|
var serializer = store.serializerFor(type.modelName),
|
2014-12-26 03:01:02 +03:00
|
|
|
payload = {};
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
serializer.serializeIntoHash(payload, type, snapshot);
|
2014-12-26 03:01:02 +03:00
|
|
|
|
|
|
|
return {data: payload};
|
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
buildIncludeURL: function (store, modelName, id, snapshot, requestType, query) {
|
|
|
|
var url = this.buildURL(modelName, id, snapshot, requestType, query),
|
|
|
|
includes = this.getEmbeddedRelations(store, modelName);
|
2014-12-26 03:01:02 +03:00
|
|
|
|
|
|
|
if (includes.length) {
|
|
|
|
url += '?include=' + includes.join(',');
|
|
|
|
}
|
|
|
|
|
|
|
|
return url;
|
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
buildQuery: function (store, modelName, options) {
|
|
|
|
var toInclude = this.getEmbeddedRelations(store, modelName),
|
2014-12-26 03:01:02 +03:00
|
|
|
query = options || {},
|
|
|
|
deDupe = {};
|
2014-07-21 01:48:24 +04:00
|
|
|
|
|
|
|
if (toInclude.length) {
|
|
|
|
// If this is a find by id, build a query object and attach the includes
|
|
|
|
if (typeof options === 'string' || typeof options === 'number') {
|
2014-12-26 03:01:02 +03:00
|
|
|
query = {};
|
2014-07-21 01:48:24 +04:00
|
|
|
query.id = options;
|
|
|
|
query.include = toInclude.join(',');
|
2014-10-25 01:09:50 +04:00
|
|
|
} else if (typeof options === 'object' || Ember.isNone(options)) {
|
|
|
|
// If this is a find all (no existing query object) build one and attach
|
|
|
|
// the includes.
|
|
|
|
// If this is a find with an existing query object then merge the includes
|
|
|
|
// into the existing object. Existing properties and includes are preserved.
|
2014-12-26 03:01:02 +03:00
|
|
|
query = query || {};
|
2014-07-21 01:48:24 +04:00
|
|
|
toInclude = toInclude.concat(query.include ? query.include.split(',') : []);
|
|
|
|
|
|
|
|
toInclude.forEach(function (include) {
|
|
|
|
deDupe[include] = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
query.include = Object.keys(deDupe).join(',');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return query;
|
2014-12-26 03:01:02 +03:00
|
|
|
},
|
|
|
|
|
2015-09-03 14:06:50 +03:00
|
|
|
getEmbeddedRelations: function (store, modelName) {
|
|
|
|
var model = store.modelFor(modelName),
|
2014-12-26 03:01:02 +03:00
|
|
|
ret = [];
|
|
|
|
|
|
|
|
// Iterate through the model's relationships and build a list
|
|
|
|
// of those that need to be pulled in via "include" from the API
|
|
|
|
model.eachRelationship(function (name, meta) {
|
|
|
|
if (meta.kind === 'hasMany' &&
|
|
|
|
Object.prototype.hasOwnProperty.call(meta.options, 'embedded') &&
|
|
|
|
meta.options.embedded === 'always') {
|
|
|
|
ret.push(name);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return ret;
|
2014-07-21 01:48:24 +04:00
|
|
|
}
|
|
|
|
});
|